Make config reloading more robust
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 3s
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 3s
This commit is contained in:
parent
31fa6bdd0c
commit
7fec8cc071
3 changed files with 102 additions and 14 deletions
|
@ -313,6 +313,11 @@ C_SIMPLE_HTTP_ParsedConfig c_simple_http_parse_config(
|
||||||
|
|
||||||
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
|
__attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
|
||||||
FILE *f = fopen(config_filename, "r");
|
FILE *f = fopen(config_filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "ERROR: Failed to open file \"%s\"!\n", config_filename);
|
||||||
|
c_simple_http_clean_up_parsed_config(&config);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
unsigned char key_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
unsigned char key_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
||||||
unsigned char value_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
unsigned char value_buf[C_SIMPLE_HTTP_CONFIG_BUF_SIZE];
|
||||||
unsigned int key_idx = 0;
|
unsigned int key_idx = 0;
|
||||||
|
|
|
@ -21,5 +21,6 @@
|
||||||
#define C_SIMPLE_HTTP_RECV_BUF_SIZE 1024
|
#define C_SIMPLE_HTTP_RECV_BUF_SIZE 1024
|
||||||
#define C_SIMPLE_HTTP_CONFIG_BUF_SIZE 1024
|
#define C_SIMPLE_HTTP_CONFIG_BUF_SIZE 1024
|
||||||
#define C_SIMPLE_HTTP_QUOTE_COUNT_MAX 3
|
#define C_SIMPLE_HTTP_QUOTE_COUNT_MAX 3
|
||||||
|
#define C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS 20
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
110
src/main.c
110
src/main.c
|
@ -91,6 +91,9 @@ int main(int argc, char **argv) {
|
||||||
"PATH",
|
"PATH",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
if (!parsed_config.hash_map) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((cleanup(cleanup_tcp_socket))) int tcp_socket =
|
__attribute__((cleanup(cleanup_tcp_socket))) int tcp_socket =
|
||||||
create_tcp_socket(args.port);
|
create_tcp_socket(args.port);
|
||||||
|
@ -157,18 +160,75 @@ int main(int argc, char **argv) {
|
||||||
ssize_t read_ret;
|
ssize_t read_ret;
|
||||||
socklen_t socket_len;
|
socklen_t socket_len;
|
||||||
|
|
||||||
|
// xxxx xxx1 - config needs to be reloaded.
|
||||||
|
unsigned int flags = 0;
|
||||||
|
const unsigned int config_try_reload_ticks =
|
||||||
|
4000000000 / C_SIMPLE_HTTP_SLEEP_NANOS;
|
||||||
|
unsigned int config_try_reload_ticks_count = 0;
|
||||||
|
unsigned int config_try_reload_attempts = 0;
|
||||||
|
|
||||||
while (C_SIMPLE_HTTP_KEEP_RUNNING) {
|
while (C_SIMPLE_HTTP_KEEP_RUNNING) {
|
||||||
nanosleep(&sleep_time, NULL);
|
nanosleep(&sleep_time, NULL);
|
||||||
|
if ((flags & 0x1) != 0) {
|
||||||
|
++config_try_reload_ticks_count;
|
||||||
|
if (config_try_reload_ticks_count >= config_try_reload_ticks) {
|
||||||
|
config_try_reload_ticks_count = 0;
|
||||||
|
++config_try_reload_attempts;
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"Attempting to reload config now (try %u of %u)...\n",
|
||||||
|
config_try_reload_attempts,
|
||||||
|
C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS);
|
||||||
|
C_SIMPLE_HTTP_ParsedConfig new_parsed_config =
|
||||||
|
c_simple_http_parse_config(
|
||||||
|
args.config_file,
|
||||||
|
"PATH",
|
||||||
|
NULL);
|
||||||
|
if (new_parsed_config.hash_map) {
|
||||||
|
c_simple_http_clean_up_parsed_config(&parsed_config);
|
||||||
|
parsed_config = new_parsed_config;
|
||||||
|
flags &= 0xFFFFFFFE;
|
||||||
|
fprintf(stderr, "Reloaded config.\n");
|
||||||
|
if (inotify_add_watch(
|
||||||
|
inotify_config_fd,
|
||||||
|
args.config_file,
|
||||||
|
IN_MODIFY | IN_CLOSE_WRITE) == -1) {
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"WARNING Failed to set listen on config, autoreloading "
|
||||||
|
"later...\n");
|
||||||
|
flags |= 1;
|
||||||
|
} else {
|
||||||
|
config_try_reload_attempts = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c_simple_http_clean_up_parsed_config(&new_parsed_config);
|
||||||
|
if (config_try_reload_attempts
|
||||||
|
>= C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS) {
|
||||||
|
fprintf(stderr, "ERROR Attempted to reload config too many times,"
|
||||||
|
" stopping!\n");
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (C_SIMPLE_HTTP_SIGUSR1_SET) {
|
if (C_SIMPLE_HTTP_SIGUSR1_SET) {
|
||||||
// Handle hot-reloading of config file due to SIGUSR1.
|
// Handle hot-reloading of config file due to SIGUSR1.
|
||||||
C_SIMPLE_HTTP_SIGUSR1_SET = 0;
|
C_SIMPLE_HTTP_SIGUSR1_SET = 0;
|
||||||
fprintf(stderr, "NOTICE SIGUSR1, reloading config file...\n");
|
fprintf(stderr, "NOTICE SIGUSR1, reloading config file...\n");
|
||||||
c_simple_http_clean_up_parsed_config(&parsed_config);
|
C_SIMPLE_HTTP_ParsedConfig new_parsed_config = c_simple_http_parse_config(
|
||||||
parsed_config = c_simple_http_parse_config(
|
|
||||||
args.config_file,
|
args.config_file,
|
||||||
"PATH",
|
"PATH",
|
||||||
NULL);
|
NULL);
|
||||||
|
if (new_parsed_config.hash_map) {
|
||||||
|
c_simple_http_clean_up_parsed_config(&parsed_config);
|
||||||
|
parsed_config = new_parsed_config;
|
||||||
|
} else {
|
||||||
|
fprintf(
|
||||||
|
stderr, "WARNING New config is invalid, keeping old config...\n");
|
||||||
|
c_simple_http_clean_up_parsed_config(&new_parsed_config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((args.flags & 0x2) != 0) {
|
if ((args.flags & 0x2) != 0) {
|
||||||
// Handle hot-reloading of config file.
|
// Handle hot-reloading of config file.
|
||||||
|
@ -191,27 +251,49 @@ int main(int argc, char **argv) {
|
||||||
if ((inotify_event->mask & IN_MODIFY) != 0
|
if ((inotify_event->mask & IN_MODIFY) != 0
|
||||||
|| (inotify_event->mask & IN_CLOSE_WRITE) != 0) {
|
|| (inotify_event->mask & IN_CLOSE_WRITE) != 0) {
|
||||||
fprintf(stderr, "NOTICE Config file modified, reloading...\n");
|
fprintf(stderr, "NOTICE Config file modified, reloading...\n");
|
||||||
c_simple_http_clean_up_parsed_config(&parsed_config);
|
C_SIMPLE_HTTP_ParsedConfig new_parsed_config =
|
||||||
parsed_config = c_simple_http_parse_config(
|
c_simple_http_parse_config(
|
||||||
args.config_file,
|
args.config_file,
|
||||||
"PATH",
|
"PATH",
|
||||||
NULL);
|
NULL);
|
||||||
|
if (new_parsed_config.hash_map) {
|
||||||
|
c_simple_http_clean_up_parsed_config(&parsed_config);
|
||||||
|
parsed_config = new_parsed_config;
|
||||||
|
} else {
|
||||||
|
fprintf(
|
||||||
|
stderr, "WARNING New config is invalid, keeping old config...\n");
|
||||||
|
c_simple_http_clean_up_parsed_config(&new_parsed_config);
|
||||||
|
}
|
||||||
} else if ((inotify_event->mask & IN_IGNORED) != 0) {
|
} else if ((inotify_event->mask & IN_IGNORED) != 0) {
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"NOTICE Config file modified (IN_IGNORED), reloading...\n");
|
"NOTICE Config file modified (IN_IGNORED), reloading...\n");
|
||||||
c_simple_http_clean_up_parsed_config(&parsed_config);
|
C_SIMPLE_HTTP_ParsedConfig new_parsed_config =
|
||||||
parsed_config = c_simple_http_parse_config(
|
c_simple_http_parse_config(
|
||||||
args.config_file,
|
args.config_file,
|
||||||
"PATH",
|
"PATH",
|
||||||
NULL);
|
NULL);
|
||||||
|
if (new_parsed_config.hash_map) {
|
||||||
|
c_simple_http_clean_up_parsed_config(&parsed_config);
|
||||||
|
parsed_config = new_parsed_config;
|
||||||
|
} else {
|
||||||
|
fprintf(
|
||||||
|
stderr, "WARNING New config is invalid, keeping old config...\n");
|
||||||
|
c_simple_http_clean_up_parsed_config(&new_parsed_config);
|
||||||
|
}
|
||||||
// Re-initialize inotify.
|
// Re-initialize inotify.
|
||||||
//c_simple_http_inotify_fd_cleanup(&inotify_config_fd);
|
//c_simple_http_inotify_fd_cleanup(&inotify_config_fd);
|
||||||
//inotify_config_fd = inotify_init1(IN_NONBLOCK);
|
//inotify_config_fd = inotify_init1(IN_NONBLOCK);
|
||||||
inotify_add_watch(
|
if (inotify_add_watch(
|
||||||
inotify_config_fd,
|
inotify_config_fd,
|
||||||
args.config_file,
|
args.config_file,
|
||||||
IN_MODIFY | IN_CLOSE_WRITE);
|
IN_MODIFY | IN_CLOSE_WRITE) == -1) {
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"WARNING Failed to set listen on config, autoreloading "
|
||||||
|
"later...\n");
|
||||||
|
flags |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue