diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-05-30 22:16:12 +0200 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-05-30 22:16:12 +0200 |
| commit | 0df4e501aee0eeaec61217312eddddc077ca53a7 (patch) | |
| tree | 5b28cfe93cd19714bf3d24123279c089bf2d777a /data/server.c | |
| parent | 2fc73d820d0442ab813c1ac11dff6d7cb1d8f50b (diff) | |
Reorganize source files in single directory
Diffstat (limited to 'data/server.c')
| -rw-r--r-- | data/server.c | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/data/server.c b/data/server.c deleted file mode 100644 index d54d853..0000000 --- a/data/server.c +++ /dev/null @@ -1,224 +0,0 @@ -#include <arpa/inet.h> -#include <json-c/json.h> -#include <signal.h> -#include <sqlite3.h> -#include <string.h> -#include <threads.h> - -#include "logger.c" -#include "sql.c" - -#define BACKLOG 10 - -struct Socket { - int fd; - struct sockaddr_in addr; -}; - -struct json_object *g_response_header; - -// ---------------------------------------------------------------------------- -// SQL callbacks -// ---------------------------------------------------------------------------- -void sql_callback_add_column_name(sqlite3_stmt *sql_stmt, void *data) { - assert(sql_stmt); - assert(data); - assert(sqlite3_column_type(sql_stmt, 0) == SQLITE_TEXT); - assert(!strcmp(sqlite3_column_name(sql_stmt, 0), "name")); - - const char *col_name = (const char *)sqlite3_column_text(sql_stmt, 0); - struct json_object *response = (struct json_object *)data; - - if (!json_object_object_get_ex(response, col_name, NULL)) { - json_object_object_add(response, col_name, json_object_new_array()); - } -} - -void sql_callback_add_data(sqlite3_stmt *sql_stmt, void *data) { - assert(sql_stmt); - assert(data); - - struct json_object *response = (struct json_object *)data; - - for (int i = 0; i < sqlite3_column_count(sql_stmt); i++) { - const char *col_name = sqlite3_column_name(sql_stmt, i); - struct json_object *col_data = json_object_object_get(response, col_name); - - if (col_data) { - if (sqlite3_column_type(sql_stmt, i) == SQLITE_BLOB) { - // TODO: render blobs in parallel - } else { - json_object_array_add(col_data, json_object_new_int64(sqlite3_column_int64(sql_stmt, i))); - } - } - } -} - -// ---------------------------------------------------------------------------- -// Main functions -// ---------------------------------------------------------------------------- -void sig_handler(int signo) { - (void)signo; - log_warn("Signal received, will stop SALIS data server"); - json_object_put(g_response_header); - sql_close(); - exit(0); -} - -void respond_name(int socket_fd) { - log_info("Client requested simulation name"); - - struct json_object *sim_name = json_object_new_object(); - json_object_object_add(sim_name, "name", json_object_new_string(NAME)); - json_object_to_fd(socket_fd, sim_name, 0); - json_object_put(sim_name); -} - -void respond_opts(int socket_fd) { - log_info("Client requested simulation options"); - - struct json_object *sim_opts = json_object_from_file(SIM_OPTS); - json_object_to_fd(socket_fd, sim_opts, 0); - json_object_put(sim_opts); -} - -void respond_hash(int socket_fd) { - log_info("Client requested git hash"); - - char buff[41] = { 0 }; - FILE *pipe = popen("git rev-parse HEAD", "r"); - fread(buff, sizeof(char), 40, pipe); - pclose(pipe); - - struct json_object *git_hash = json_object_new_object(); - json_object_object_add(git_hash, "hash", json_object_new_string(buff)); - json_object_to_fd(socket_fd, git_hash, 0); - json_object_put(git_hash); -} - -void respond_data(int socket_fd, struct json_object *request) { - assert(request); - - const char *request_str = json_object_to_json_string(request); - log_info("Client requested simulation data with the following parameters: %s", request_str); - const char *x_axis = json_object_get_string(json_object_object_get(request, "x-axis")); - int64_t x_current = json_object_get_int64(json_object_object_get(request, "x-current")); - int64_t x_high = json_object_get_int64(json_object_object_get(request, "x-high")); - int64_t nth = json_object_get_int64(json_object_object_get(request, "nth")); - int64_t entries = json_object_get_int64(json_object_object_get(request, "entries")); - - const char *x_axis_pref = (!strcmp(x_axis, "rowid") || !strcmp(x_axis, "step")) ? "core." : ""; - - struct json_object *response = NULL; - json_object_deep_copy(g_response_header, &response, NULL); - - sql_exec( - 0, NULL, NULL, - sql_callback_add_data, - response, - "select * from (" - "select core.rowid, core.step, * from core inner join arch " - "where core.rowid = arch.rowid and %s%s > %ld and %s%s <= %ld and core.rowid %% %ld == 0 " - "order by %s%s desc limit %ld" - ") order by %s asc;", - x_axis_pref, - x_axis, - x_current, - x_axis_pref, - x_axis, - x_high, - nth, - x_axis_pref, - x_axis, - entries, - x_axis - ); - - const char *response_str = json_object_to_json_string(response); - log_info("Responding to client with: %s", response_str); - json_object_to_fd(socket_fd, response, 0); - json_object_put(response); - - shutdown(socket_fd, SHUT_WR); -} - -int handle_client(struct Socket *socket) { - assert(socket); - - char socket_ip[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &socket->addr.sin_addr, socket_ip, INET_ADDRSTRLEN); - log_info("Client connected: %s:%d", socket_ip, ntohs(socket->addr.sin_port)); - - struct json_object *request_json = json_object_from_fd(socket->fd); - struct json_object *request_str = NULL; - - if (!json_object_object_get_ex(request_json, "request", &request_str)) assert(false); - - const char *request = json_object_get_string(request_str); - assert(request); - - if (!strcmp(request, "name")) { - respond_name(socket->fd); - } else if (!strcmp(request, "opts")) { - respond_opts(socket->fd); - } else if (!strcmp(request, "hash")) { - respond_hash(socket->fd); - } else if (!strcmp(request, "data")) { - respond_data(socket->fd, request_json); - } else { - assert(false); - } - - json_object_put(request_json); - - log_info("Client disconnected: %s:%d", socket_ip, ntohs(socket->addr.sin_port)); - close(socket->fd); - - free(socket); - return 0; -} - -int main(void) { - log_info("Initializing salis data server"); - log_info("Connecting to database in: %s", DATA_PUSH_PATH); - sql_open(); - - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - log_info("Creating response header"); - g_response_header = json_object_new_object(); - json_object_object_add(g_response_header, "rowid", json_object_new_array()); - sql_exec( - 0, NULL, NULL, - sql_callback_add_column_name, - g_response_header, - "select name from pragma_table_info('core') union " - "select name from pragma_table_info('arch');" - ); - - log_info("Binding to port: %d", PORT); - int opt = 1; - int socket_fd = socket(AF_INET, SOCK_STREAM, 0); - setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - struct sockaddr_in socket_addr = { 0 }; - socket_addr.sin_family = AF_INET; - socket_addr.sin_addr.s_addr = INADDR_ANY; - socket_addr.sin_port = htons(PORT); - bind(socket_fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)); - - listen(socket_fd, BACKLOG); - log_info("Listening..."); - - while (true) { - struct Socket *socket = calloc(1, sizeof(struct Socket)); - socklen_t socket_len = sizeof(struct sockaddr_in); - socket->fd = accept(socket_fd, (struct sockaddr *)&socket->addr, &socket_len); - - thrd_t thrd; - thrd_create(&thrd, (thrd_start_t)handle_client, socket); - thrd_detach(thrd); - } - - return 0; -} |
