diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2023-05-13 08:59:43 +0200 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2023-05-13 11:37:46 +0200 |
commit | f471fbdf27462b82febe4e8db8358ab3380d2a28 (patch) | |
tree | 6c41abf4e32214cd8bdb0f8a377f93b3c7c0d830 /src/server.c | |
parent | ci_queue: fix a broken getter (diff) | |
download | cimple-f471fbdf27462b82febe4e8db8358ab3380d2a28.tar.gz cimple-f471fbdf27462b82febe4e8db8358ab3380d2a28.zip |
add command module to handle request-response communications
Diffstat (limited to '')
-rw-r--r-- | src/server.c | 129 |
1 files changed, 39 insertions, 90 deletions
diff --git a/src/server.c b/src/server.c index 22a9a86..806da11 100644 --- a/src/server.c +++ b/src/server.c @@ -7,6 +7,7 @@ #include "server.h" #include "ci_queue.h" +#include "command.h" #include "compiler.h" #include "const.h" #include "log.h" @@ -18,7 +19,6 @@ #include <pthread.h> #include <stdlib.h> -#include <string.h> struct server { pthread_mutex_t server_mtx; @@ -111,7 +111,7 @@ static int server_has_runs(const struct server *server) static int worker_ci_run(int fd, const struct ci_queue_entry *ci_run) { - struct msg request, response; + struct msg *request, *response; int ret = 0; const char *argv[] = {CMD_CI_RUN, ci_queue_entry_get_url(ci_run), @@ -121,21 +121,21 @@ static int worker_ci_run(int fd, const struct ci_queue_entry *ci_run) if (ret < 0) return ret; - ret = msg_send_and_wait(fd, &request, &response); - msg_free(&request); + ret = msg_send_and_wait(fd, request, &response); + msg_free(request); if (ret < 0) return ret; - if (response.argc < 0) { + if (!msg_is_success(response)) { log_err("Failed to schedule a CI run: worker is busy?\n"); - ret = -1; + msg_dump(response); goto free_response; } /* TODO: handle the response. */ free_response: - msg_free(&response); + msg_free(response); return ret; } @@ -234,15 +234,10 @@ static int worker_thread(struct server *server, int fd) return ret; } -static int msg_new_worker_handler(struct server *server, int client_fd, - UNUSED const struct msg *request) +static int msg_new_worker_handler(int client_fd, UNUSED const struct msg *request, void *_server, + UNUSED struct msg **response) { - return worker_thread(server, client_fd); -} - -static int msg_new_worker_parser(UNUSED const struct msg *msg) -{ - return 1; + return worker_thread((struct server *)_server, client_fd); } static int msg_ci_run_queue(struct server *server, const char *url, const char *rev) @@ -276,87 +271,33 @@ unlock: return ret; } -static int msg_ci_run_handler(struct server *server, int client_fd, const struct msg *msg) +static int msg_ci_run_handler(UNUSED int client_fd, const struct msg *request, void *_server, + struct msg **response) { - struct msg response; + struct server *server = (struct server *)_server; int ret = 0; - ret = msg_ci_run_queue(server, msg->argv[1], msg->argv[2]); - if (ret < 0) - ret = msg_error(&response); - else - ret = msg_success(&response); - - if (ret < 0) - return ret; - - ret = msg_send(client_fd, &response); - msg_free(&response); - return ret; -} - -static int msg_ci_run_parser(const struct msg *msg) -{ - if (msg->argc != 3) { - log_err("Invalid number of arguments for a message: %d\n", msg->argc); - return 0; - } - - return 1; -} - -typedef int (*msg_parser)(const struct msg *msg); -typedef int (*msg_handler)(struct server *, int client_fd, const struct msg *msg); - -struct msg_descr { - const char *cmd; - msg_parser parser; - msg_handler handler; -}; - -struct msg_descr messages[] = { - {CMD_NEW_WORKER, msg_new_worker_parser, msg_new_worker_handler}, - {CMD_CI_RUN, msg_ci_run_parser, msg_ci_run_handler}, -}; - -static int server_msg_handler(struct server *server, int client_fd, const struct msg *request) -{ - if (request->argc == 0) - goto unknown_request; - - size_t numof_messages = sizeof(messages) / sizeof(messages[0]); - - for (size_t i = 0; i < numof_messages; ++i) { - if (strcmp(messages[i].cmd, request->argv[0])) - continue; - if (!messages[i].parser(request)) - continue; - return messages[i].handler(server, client_fd, request); + if (msg_get_length(request) != 3) { + log_err("Invalid number of arguments for a message: %zu\n", + msg_get_length(request)); + msg_dump(request); + return -1; } -unknown_request: - log_err("Received an unknown message\n"); - msg_dump(request); - struct msg response; - msg_error(&response); - return msg_send(client_fd, &response); -} - -static int server_conn_handler(int client_fd, void *_server) -{ - struct server *server = (struct server *)_server; - struct msg request; - int ret = 0; + const char **words = msg_get_words(request); - ret = msg_recv(client_fd, &request); + ret = msg_ci_run_queue(server, words[1], words[2]); if (ret < 0) return ret; - ret = server_msg_handler(server, client_fd, &request); - msg_free(&request); - return ret; + return msg_success(response); } +static struct command_def commands[] = { + {CMD_NEW_WORKER, msg_new_worker_handler}, + {CMD_CI_RUN, msg_ci_run_handler}, +}; + static int server_set_stopping(struct server *server) { int ret = 0; @@ -383,24 +324,32 @@ unlock: int server_main(struct server *server) { + struct command_dispatcher *dispatcher = NULL; int ret = 0; ret = signal_install_global_handler(); if (ret < 0) return ret; + ret = command_dispatcher_create(&dispatcher, commands, + sizeof(commands) / sizeof(commands[0]), server); + if (ret < 0) + return ret; + while (!global_stop_flag) { log("Waiting for new connections\n"); - ret = tcp_server_accept(server->tcp_server, server_conn_handler, server); + ret = tcp_server_accept(server->tcp_server, command_dispatcher_conn_handler, + dispatcher); if (ret < 0) { - if (errno == EINVAL && global_stop_flag) { + if (errno == EINVAL && global_stop_flag) ret = 0; - break; - } - return ret; + goto dispatcher_destroy; } } +dispatcher_destroy: + command_dispatcher_destroy(dispatcher); + return server_set_stopping(server); } |