MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
lila_server.cpp
Go to the documentation of this file.
1/**
2 * @file lila_server.cpp
3 * @brief Entry point for the Lila live coding TCP server binary.
4 *
5 * This program launches the Lila server, which enables interactive live coding sessions
6 * over TCP for MayaFlux. It parses command-line options for port, verbosity, and log level,
7 * sets up signal handling for graceful shutdown, and manages the main server loop.
8 *
9 * Usage:
10 * lila_server [OPTIONS]
11 *
12 * Options:
13 * -p, --port <port> Server port (default: 9090)
14 * -v, --verbose Enable verbose logging
15 * -l, --level <level> Set log level (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
16 * -h, --help Show help message
17 */
18
19#include "Lila/Commentator.hpp"
20#include "Lila/Lila.hpp"
21
22#include "Lila/EventBus.hpp"
23
24#include <atomic>
25#include <csignal>
26#include <iostream>
27
28/**
29 * @brief Global flag to control server running state.
30 */
31std::atomic<bool> g_running { true };
32
33/**
34 * @brief Handles SIGINT and SIGTERM for graceful shutdown.
35 * @param signal Signal number
36 */
37void signal_handler(int signal)
38{
39 if (signal == SIGINT || signal == SIGTERM) {
40 LILA_INFO(Lila::Emitter::SYSTEM, "Received shutdown signal");
41 g_running = false;
42 }
43}
44
45/**
46 * @brief Prints usage information for the server binary.
47 * @param program_name Name of the executable
48 */
49void print_usage(const char* program_name)
50{
51 std::cout << "Usage: " << program_name << " [OPTIONS]\n"
52 << "\nOptions:\n"
53 << " -p, --port <port> Server port (default: 9090)\n"
54 << " -v, --verbose Enable verbose logging\n"
55 << " -l, --level <level> Set log level (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)\n"
56 << " -h, --help Show this help message\n"
57 << "\nExamples:\n"
58 << " " << program_name << " # Start on default port 9090\n"
59 << " " << program_name << " -p 8080 # Start on port 8080\n"
60 << " " << program_name << " -v -l DEBUG # Verbose mode with DEBUG level\n"
61 << '\n';
62}
63
64/**
65 * @brief Parses a string to a Lila::LogLevel value.
66 * @param level_str Log level string
67 * @return Corresponding LogLevel enum value
68 */
69Lila::LogLevel parse_log_level(const std::string& level_str)
70{
71 if (level_str == "TRACE")
72 return Lila::LogLevel::TRACE;
73 if (level_str == "DEBUG")
74 return Lila::LogLevel::DEBUG;
75 if (level_str == "INFO")
76 return Lila::LogLevel::INFO;
77 if (level_str == "WARN")
78 return Lila::LogLevel::WARN;
79 if (level_str == "ERROR")
80 return Lila::LogLevel::ERROR;
81 if (level_str == "FATAL")
82 return Lila::LogLevel::FATAL;
83
84 LILA_WARN(Lila::Emitter::SYSTEM,
85 std::string("Unknown log level '") + level_str + "', using INFO");
86 return Lila::LogLevel::INFO;
87}
88
89/**
90 * @brief Main entry point for the Lila server binary.
91 * @param argc Argument count
92 * @param argv Argument vector
93 * @return Exit code
94 */
95int main(int argc, char** argv)
96{
97 int port = 9090;
98 bool verbose = false;
99 Lila::LogLevel log_level = Lila::LogLevel::INFO;
100
101 for (int i = 1; i < argc; ++i) {
102 std::string arg = argv[i];
103
104 if (arg == "-h" || arg == "--help") {
105 print_usage(argv[0]);
106 return 0;
107 }
108
109 if (arg == "-p" || arg == "--port") {
110 if (i + 1 < argc) {
111 port = std::atoi(argv[++i]);
112 if (port <= 0 || port > 65535) {
113 std::cerr << "Error: Invalid port number\n";
114 return 1;
115 }
116 } else {
117 std::cerr << "Error: --port requires an argument\n";
118 return 1;
119 }
120 } else if (arg == "-v" || arg == "--verbose") {
121 verbose = true;
122 } else if (arg == "-l" || arg == "--level") {
123 if (i + 1 < argc) {
124 log_level = parse_log_level(argv[++i]);
125 } else {
126 std::cerr << "Error: --level requires an argument\n";
127 return 1;
128 }
129 } else {
130 std::cerr << "Error: Unknown option '" << arg << "'\n";
131 print_usage(argv[0]);
132 return 1;
133 }
134 }
135
136 auto& logger = Lila::Commentator::instance();
137 logger.set_level(log_level);
138 logger.set_verbose(verbose);
139
140 std::signal(SIGINT, signal_handler);
141 std::signal(SIGTERM, signal_handler);
142
143 LILA_INFO(Lila::Emitter::SYSTEM, "Starting Lila live coding server");
144 LILA_INFO(Lila::Emitter::SYSTEM, std::string("Port: ") + std::to_string(port));
145
146 std::string level_str;
147 switch (log_level) {
148 case Lila::LogLevel::TRACE:
149 level_str = "TRACE";
150 break;
151 case Lila::LogLevel::DEBUG:
152 level_str = "DEBUG";
153 break;
154 case Lila::LogLevel::INFO:
155 level_str = "INFO";
156 break;
157 case Lila::LogLevel::WARN:
158 level_str = "WARN";
159 break;
160 case Lila::LogLevel::ERROR:
161 level_str = "ERROR";
162 break;
163 case Lila::LogLevel::FATAL:
164 level_str = "FATAL";
165 break;
166 default:
167 level_str = "UNKNOWN";
168 break;
169 }
170 LILA_INFO(Lila::Emitter::SYSTEM, std::string("Log level: ") + level_str);
171
172 if (verbose) {
173 LILA_INFO(Lila::Emitter::SYSTEM, "Verbose mode enabled");
174 }
175
176 Lila::Lila playground;
177
178 if (!playground.initialize(Lila::OperationMode::Server, port)) {
179 LILA_FATAL(Lila::Emitter::SYSTEM,
180 std::string("Failed to initialize: ") + playground.get_last_error());
181 return 1;
182 }
183
184 playground.on_server_started([]() {
185 std::cout << "LILA_SERVER_READY\n"
186 << std::flush;
187 LILA_INFO(Lila::Emitter::SYSTEM, "Server is ready to accept connections");
188 });
189
190 playground.on_success([]() {
191 LILA_INFO(Lila::Emitter::GENERAL, "Code evaluation succeeded");
192 });
193
194 /*
195 playground.on_error([](const std::string& error) {
196 LILA_ERROR(Lila::Emitter::GENERAL,
197 std::string("Evaluation error: ") + error);
198 });
199 */
200
201 playground.on_server_client_connected([](const Lila::ClientInfo& client) {
202 LILA_INFO(Lila::Emitter::SERVER,
203 std::string("New client connection (fd: ") + std::to_string(client.fd) + ", session: " + (client.session_id.empty() ? "none" : client.session_id) + ")");
204 });
205
206 playground.on_server_client_disconnected([](const Lila::ClientInfo& client) {
207 LILA_INFO(Lila::Emitter::SERVER,
208 std::string("Client disconnected (fd: ") + std::to_string(client.fd) + ", session: " + (client.session_id.empty() ? "none" : client.session_id) + ")");
209 });
210
211 LILA_INFO(Lila::Emitter::SYSTEM, "Server running. Press Ctrl+C to stop.");
212
213 while (g_running) {
214 if (!playground.is_server_running()) {
215 LILA_ERROR(Lila::Emitter::SYSTEM, "Server stopped unexpectedly");
216 break;
217 }
218 std::this_thread::sleep_for(std::chrono::milliseconds(100));
219 }
220
221 LILA_INFO(Lila::Emitter::SYSTEM, "Shutting down...");
222 playground.stop_server();
223 LILA_INFO(Lila::Emitter::SYSTEM, "Goodbye!");
224
225 return 0;
226}
#define LILA_WARN(emitter, msg)
#define LILA_ERROR(emitter, msg)
#define LILA_INFO(emitter, msg)
#define LILA_FATAL(emitter, msg)
static Commentator & instance()
void stop_server()
Stops the TCP server and disconnects all clients.
Definition Lila.cpp:128
void on_server_client_disconnected(std::function< void(const ClientInfo &)> callback)
Registers a callback for client disconnections (server mode)
Definition Lila.cpp:194
bool initialize(OperationMode mode=OperationMode::Direct, int server_port=9090) noexcept
Initializes the live coding environment.
Definition Lila.cpp:23
void on_server_client_connected(std::function< void(const ClientInfo &)> callback)
Registers a callback for new client connections (server mode)
Definition Lila.cpp:186
std::string get_last_error() const
Gets the last error message.
Definition Lila.cpp:202
bool is_server_running() const
Checks if the server is currently running.
Definition Lila.cpp:137
void on_success(std::function< void()> callback)
Registers a callback for successful code evaluation.
Definition Lila.cpp:166
void on_server_started(std::function< void()> callback)
Registers a callback for server start events.
Definition Lila.cpp:178
void signal_handler(int signal)
Handles SIGINT and SIGTERM for graceful shutdown.
Lila::LogLevel parse_log_level(const std::string &level_str)
Parses a string to a Lila::LogLevel value.
std::atomic< bool > g_running
Global flag to control server running state.
void print_usage(const char *program_name)
Prints usage information for the server binary.
int main()
Definition main.cpp:33
std::string session_id
Session identifier (if set)
Definition EventBus.hpp:60
int fd
Client socket file descriptor.
Definition EventBus.hpp:59
Information about a connected client.
Definition EventBus.hpp:58