122 lines
3.9 KiB
C++
122 lines
3.9 KiB
C++
#include <iostream>
|
|
#include <exception>
|
|
#include <csignal>
|
|
#include <atomic>
|
|
#include <string>
|
|
|
|
#include "config.hpp"
|
|
#include "database.hpp"
|
|
#include "server.hpp"
|
|
|
|
std::atomic<bool> stopServer{false};
|
|
|
|
void signalHandler(int signal) {
|
|
if (signal == SIGINT || signal == SIGTERM) {
|
|
std::cout << "\nReceived shutdown signal. Stopping server..." << std::endl;
|
|
stopServer = true;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
try {
|
|
std::string configFile = "config.json";
|
|
bool debug = false;
|
|
bool configFileSpecified = false;
|
|
|
|
for (int i = 1; i < argc; ++i) {
|
|
const std::string argument = argv[i];
|
|
if (argument == "--debug") {
|
|
debug = true;
|
|
} else if (argument.starts_with("--")) {
|
|
throw std::invalid_argument("Unknown option: " + argument);
|
|
} else if (configFileSpecified) {
|
|
throw std::invalid_argument("Only one configuration file can be specified");
|
|
} else {
|
|
configFile = argument;
|
|
configFileSpecified = true;
|
|
}
|
|
}
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Debug mode enabled" << std::endl;
|
|
std::cout << "[debug] Configuration file: " << configFile << std::endl;
|
|
}
|
|
|
|
std::cout << "Loading configuration from: " << configFile << std::endl;
|
|
AppConfig config = AppConfig::loadFromFile(configFile);
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Server configuration: address=" << config.server.address
|
|
<< ", port=" << config.server.port
|
|
<< ", threads=" << config.server.threads << std::endl;
|
|
std::cout << "[debug] Database configuration: host=" << config.database.host
|
|
<< ", port=" << config.database.port
|
|
<< ", dbname=" << config.database.dbname
|
|
<< ", user=" << config.database.user
|
|
<< ", password=" << (config.database.password.empty() ? "not set" : "set")
|
|
<< std::endl;
|
|
std::cout << "[debug] Initializing database connection pool" << std::endl;
|
|
}
|
|
|
|
std::cout << "Connecting to database..." << std::endl;
|
|
auto db = std::make_shared<Database>(config.database, 2, debug);
|
|
std::cout << "Database connected successfully!" << std::endl;
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Creating HTTP server" << std::endl;
|
|
}
|
|
|
|
Server server(
|
|
config.server.address,
|
|
config.server.port,
|
|
config.server.threads,
|
|
db
|
|
);
|
|
|
|
std::signal(SIGINT, signalHandler);
|
|
std::signal(SIGTERM, signalHandler);
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] SIGINT and SIGTERM handlers installed" << std::endl;
|
|
}
|
|
|
|
std::cout << "Server is running on "
|
|
<< config.server.address << ":"
|
|
<< config.server.port
|
|
<< " with " << config.server.threads << " threads" << std::endl;
|
|
std::cout << "Press Ctrl+C to stop" << std::endl;
|
|
|
|
std::thread serverThread([&server]() {
|
|
server.run();
|
|
});
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Server thread started" << std::endl;
|
|
}
|
|
|
|
while (!stopServer) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
}
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Stopping I/O context" << std::endl;
|
|
}
|
|
|
|
std::cout << "Stopping server..." << std::endl;
|
|
server.stop();
|
|
serverThread.join();
|
|
|
|
if (debug) {
|
|
std::cout << "[debug] Server thread joined" << std::endl;
|
|
}
|
|
|
|
std::cout << "Server stopped successfully!" << std::endl;
|
|
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Error: " << e.what() << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|