Keep FastCGI available during restarts
This commit is contained in:
+57
-13
@@ -699,15 +699,7 @@ volatile bool termination_signal_received = false;
|
||||
|
||||
void on_terminate(int sig)
|
||||
{
|
||||
if(termination_signal_received)
|
||||
return;
|
||||
termination_signal_received = true;
|
||||
if(getpid() != parent_pid)
|
||||
exit(1);
|
||||
printf("Terminating... PID %i:%i\n", getpid(), parent_pid);
|
||||
wasm_backend_shutdown();
|
||||
server.shutdown();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void clear_shared_unit_cache(ServerState& state)
|
||||
@@ -1069,7 +1061,7 @@ void run_ws_broker()
|
||||
ws_broker.listen(server_state.config["WS_BROKER_SOCKET_PATH"]);
|
||||
chmod(server_state.config["WS_BROKER_SOCKET_PATH"].c_str(), S_IRWXU | S_IRGRP | S_IWGRP);
|
||||
}
|
||||
for(;;)
|
||||
while(!termination_signal_received)
|
||||
{
|
||||
ws_broker.process(50);
|
||||
ws_broker_drain_outbound(ws_broker_outbound_timeout_seconds);
|
||||
@@ -1254,7 +1246,7 @@ void run_proactive_compiler()
|
||||
}
|
||||
next_scan_at = time_precise();
|
||||
|
||||
for(;;)
|
||||
while(!termination_signal_received)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1397,10 +1389,21 @@ void listen_for_connections()
|
||||
printf("(P) wasm worker ready: PID %i in %.3f ms\n", getpid(), wasm_ms);
|
||||
else
|
||||
fprintf(stderr, "(!) wasm worker initialization failed: PID %i in %.3f ms: %s\n", getpid(), wasm_ms, wasm_error.c_str());
|
||||
for(;;)
|
||||
while(!termination_signal_received)
|
||||
{
|
||||
server.process(-1);
|
||||
}
|
||||
close_inherited_server_sockets();
|
||||
f64 drain_deadline = time_precise() + (f64)to_u64(server_state.config["WORKER_DRAIN_TIMEOUT_SECONDS"], 10);
|
||||
while(!server.client_sockets.empty() && time_precise() < drain_deadline)
|
||||
server.process(100);
|
||||
if(!server.client_sockets.empty())
|
||||
fprintf(stderr, "(!) worker PID %i drain deadline reached with %zu client connections\n",
|
||||
getpid(), server.client_sockets.size());
|
||||
else
|
||||
printf("(P) worker PID %i drained cleanly\n", getpid());
|
||||
wasm_backend_shutdown();
|
||||
exit(server.client_sockets.empty() ? 0 : 1);
|
||||
}
|
||||
|
||||
mode_t configured_socket_mode(String value, mode_t fallback)
|
||||
@@ -1424,6 +1427,25 @@ void chmod_configured_socket(String path, String mode_value, mode_t fallback)
|
||||
fprintf(stderr, "(!) Could not chmod socket %s to %04o: %s\n", path.c_str(), (unsigned int)mode, strerror(errno));
|
||||
}
|
||||
|
||||
int systemd_fastcgi_listener()
|
||||
{
|
||||
const char* listen_pid = getenv("LISTEN_PID");
|
||||
const char* listen_fds = getenv("LISTEN_FDS");
|
||||
if(!listen_pid || !listen_fds)
|
||||
return(-1);
|
||||
if(to_u64(listen_pid, 0) != (u64)getpid())
|
||||
return(-1);
|
||||
if(to_u64(listen_fds, 0) != 1)
|
||||
throw std::runtime_error("UCE requires exactly one systemd FastCGI listener");
|
||||
const char* names = getenv("LISTEN_FDNAMES");
|
||||
if(names && names[0] != '\0' && String(names) != "fastcgi")
|
||||
throw std::runtime_error("systemd listener must be named fastcgi");
|
||||
unsetenv("LISTEN_PID");
|
||||
unsetenv("LISTEN_FDS");
|
||||
unsetenv("LISTEN_FDNAMES");
|
||||
return(3);
|
||||
}
|
||||
|
||||
StringMap redacted_server_config_for_log(const StringMap& config)
|
||||
{
|
||||
StringMap redacted = config;
|
||||
@@ -1443,13 +1465,16 @@ void init_base_process()
|
||||
server_state.config = make_server_settings();
|
||||
server_state.config["COMPILER_SYS_PATH"] = cwd_get();
|
||||
printf("Compiler base path: %s\n", server_state.config["COMPILER_SYS_PATH"].c_str());
|
||||
int inherited_fastcgi = systemd_fastcgi_listener();
|
||||
if(inherited_fastcgi >= 0)
|
||||
server.adopt_listener(inherited_fastcgi, 'F');
|
||||
|
||||
if(server_state.config["FCGI_PORT"] != "")
|
||||
server.listen(int_val(server_state.config["FCGI_PORT"]));
|
||||
|
||||
printf("%s\n", var_dump(redacted_server_config_for_log(server_state.config)).c_str());
|
||||
|
||||
if(server_state.config["FCGI_SOCKET_PATH"] != "")
|
||||
if(inherited_fastcgi < 0 && server_state.config["FCGI_SOCKET_PATH"] != "")
|
||||
{
|
||||
server.listen(server_state.config["FCGI_SOCKET_PATH"]);
|
||||
chmod_configured_socket(server_state.config["FCGI_SOCKET_PATH"], server_state.config["FCGI_SOCKET_MODE"], 0666);
|
||||
@@ -1469,7 +1494,9 @@ void init_base_process()
|
||||
mkdir(server_state.config["SESSION_PATH"]);
|
||||
|
||||
signal(SIGCHLD, on_child_exit);
|
||||
signal(SIGTERM, on_terminate);
|
||||
signal(SIGINT, on_terminate);
|
||||
signal(SIGHUP, on_terminate);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
srand(time());
|
||||
}
|
||||
@@ -1489,7 +1516,7 @@ int main(int argc, char** argv)
|
||||
ensure_proactive_compiler();
|
||||
ensure_ws_broker();
|
||||
|
||||
for(;;)
|
||||
while(!termination_signal_received)
|
||||
{
|
||||
if(!proactive_compiler_alive())
|
||||
proactive_compiler_pid = 0;
|
||||
@@ -1512,5 +1539,22 @@ int main(int argc, char** argv)
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf("(P) draining %zu workers before shutdown\n", workers.size());
|
||||
for(auto& worker : workers)
|
||||
kill(worker.first, SIGTERM);
|
||||
if(proactive_compiler_pid > 0)
|
||||
kill(proactive_compiler_pid, SIGTERM);
|
||||
if(ws_broker_pid > 0)
|
||||
kill(ws_broker_pid, SIGTERM);
|
||||
f64 drain_deadline = time_precise() + (f64)to_u64(server_state.config["WORKER_DRAIN_TIMEOUT_SECONDS"], 10);
|
||||
while(!workers.empty() && time_precise() < drain_deadline)
|
||||
{
|
||||
on_child_exit(0);
|
||||
usleep(10000);
|
||||
}
|
||||
for(auto& worker : workers)
|
||||
kill(worker.first, SIGKILL);
|
||||
server.shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user