Files
weaseldb/src/main.cpp

139 lines
4.6 KiB
C++

#include "config.hpp"
#include "connection.hpp"
#include "connection_handler.hpp"
#include "http_handler.hpp"
#include "perfetto_categories.hpp"
#include "server.hpp"
#include <atomic>
#include <csignal>
#include <iostream>
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
// TODO this should be scoped to a particular Server, and it's definition should
// be in server.cpp or connection.cpp
std::atomic<int> activeConnections{0};
// Global server instance for signal handler access
static Server *g_server = nullptr;
void signal_handler(int sig) {
if (sig == SIGTERM || sig == SIGINT) {
if (g_server) {
g_server->shutdown();
}
}
}
void print_help(const char *program_name) {
std::cout << "WeaselDB - High-performance write-side database component\n\n";
std::cout << "Usage: " << program_name << " [OPTIONS]\n\n";
std::cout << "Options:\n";
std::cout << " --config <file> Path to TOML configuration file (default: "
"config.toml)\n";
std::cout << " --help Show this help message and exit\n";
std::cout << " -h Show this help message and exit\n\n";
std::cout << "Examples:\n";
std::cout << " " << program_name
<< " # Use default config.toml\n";
std::cout << " " << program_name
<< " --config my.toml # Use custom config file\n";
std::cout << " " << program_name
<< " --help # Show this help\n\n";
std::cout << "For configuration documentation, see config.md\n";
}
int main(int argc, char *argv[]) {
#if ENABLE_PERFETTO
perfetto::TracingInitArgs args;
args.backends |= perfetto::kSystemBackend;
perfetto::Tracing::Initialize(args);
perfetto::TrackEvent::Register();
#endif
std::string config_file = "config.toml";
// Parse command line arguments
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--help" || arg == "-h") {
print_help(argv[0]);
return 0;
} else if (arg == "--config") {
if (i + 1 >= argc) {
std::cerr << "Error: --config requires a filename argument\n";
print_help(argv[0]);
return 1;
}
config_file = argv[++i];
} else if (arg.starts_with("--config=")) {
config_file = arg.substr(9);
} else {
// For backward compatibility, treat lone argument as config file
if (argc == 2) {
config_file = arg;
} else {
std::cerr << "Error: Unknown argument '" << arg << "'\n";
print_help(argv[0]);
return 1;
}
}
}
auto config = weaseldb::ConfigParser::load_from_file(config_file);
if (!config) {
std::cerr << "Failed to load config from: " << config_file << std::endl;
std::cerr << "Using default configuration..." << std::endl;
config = weaseldb::Config{};
}
std::cout << "Configuration loaded successfully:" << std::endl;
if (!config->server.unix_socket_path.empty()) {
std::cout << "Unix socket path: " << config->server.unix_socket_path
<< std::endl;
} else {
std::cout << "Server bind address: " << config->server.bind_address
<< std::endl;
std::cout << "Server port: " << config->server.port << std::endl;
}
std::cout << "Max request size: " << config->server.max_request_size_bytes
<< " bytes" << std::endl;
std::cout << "I/O threads: " << config->server.io_threads << std::endl;
std::cout << "Event batch size: " << config->server.event_batch_size
<< std::endl;
std::cout << "Max connections: " << config->server.max_connections
<< std::endl;
std::cout << "Read buffer size: " << config->server.read_buffer_size
<< " bytes" << std::endl;
std::cout << "Min request ID length: " << config->commit.min_request_id_length
<< std::endl;
std::cout << "Request ID retention: "
<< config->commit.request_id_retention_hours.count() << " hours"
<< std::endl;
std::cout << "Subscription buffer size: "
<< config->subscription.max_buffer_size_bytes << " bytes"
<< std::endl;
std::cout << "Keepalive interval: "
<< config->subscription.keepalive_interval.count() << " seconds"
<< std::endl;
// Create handler and server
HttpHandler http_handler;
auto server = Server::create(*config, http_handler);
g_server = server.get();
// Setup signal handling
signal(SIGPIPE, SIG_IGN);
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
std::cout << "Starting WeaselDB HTTP server..." << std::endl;
server->run();
std::cout << "Server shutdown complete." << std::endl;
g_server = nullptr;
return 0;
}