Keep demand compilation responsive

This commit is contained in:
udo
2026-07-18 11:14:40 +00:00
parent 495a8ae5f0
commit 0e0c0b6ccc
2 changed files with 104 additions and 49 deletions
+96 -48
View File
@@ -16,6 +16,7 @@ ServerState server_state;
FastCGIServer server;
pid_t proactive_compiler_pid = 0;
pid_t priority_compiler_pid = 0;
// The central WS broker process: owns the WS port + every connection, forwards
// renders to the worker pool over uce.sock, and applies ws_* commands flushed
@@ -1217,6 +1218,39 @@ void proactive_compile_queue_push(StringList& queue, String file_name)
queue.push_back(file_name);
}
bool proactive_compile_unit(Request& context, String file_name, bool& source_missing)
{
bool failed = false;
String wasm_path = server_state.config["BIN_DIRECTORY"] + file_name + ".wasm";
if(compiler_unit_needs_recompile(&context, file_name, &source_missing))
{
printf("(i) proactive compile %s\n", file_name.c_str());
auto su = get_shared_unit(&context, file_name);
failed = !su || su->compiler_messages != "";
if(su)
wasm_path = su->wasm_name;
}
else if(source_missing)
{
printf("(i) proactive compiler forget removed unit %s\n", file_name.c_str());
compiler_untrack_known_unit(&context, file_name);
}
if(!source_missing && !failed && wasm_serialized_module_needs_refresh(wasm_path))
{
printf("(i) proactive serialize %s\n", file_name.c_str());
String serialize_error = wasm_serialize_module_artifact(wasm_path);
if(serialize_error != "")
{
printf("(!) proactive serialize failed for %s: %s\n", file_name.c_str(), serialize_error.c_str());
failed = true;
}
}
context.session.clear();
context.session_loaded_hash = "";
clear_shared_unit_cache(server_state);
return(failed);
}
void run_proactive_compiler()
{
Request background_context;
@@ -1317,39 +1351,13 @@ void run_proactive_compiler()
auto retry_it = retry_after.find(file_name);
if(retry_it != retry_after.end() && time_precise() < retry_it->second)
continue;
bool failed = false;
String wasm_path = server_state.config["BIN_DIRECTORY"] + file_name + ".wasm";
if(compiler_unit_needs_recompile(&background_context, file_name, &source_missing))
{
printf("(i) proactive compile %s\n", file_name.c_str());
auto su = get_shared_unit(&background_context, file_name);
failed = !su || su->compiler_messages != "";
if(su)
wasm_path = su->wasm_name;
}
else if(source_missing)
{
printf("(i) proactive compiler forget removed unit %s\n", file_name.c_str());
compiler_untrack_known_unit(&background_context, file_name);
bool failed = proactive_compile_unit(background_context, file_name, source_missing);
if(source_missing)
retry_after.erase(file_name);
}
if(!source_missing && !failed && wasm_serialized_module_needs_refresh(wasm_path))
{
printf("(i) proactive serialize %s\n", file_name.c_str());
String serialize_error = wasm_serialize_module_artifact(wasm_path);
if(serialize_error != "")
{
printf("(!) proactive serialize failed for %s: %s\n", file_name.c_str(), serialize_error.c_str());
failed = true;
}
}
if(!source_missing && failed)
else if(failed)
retry_after[file_name] = time_precise() + failure_retry_interval;
else if(!source_missing)
else
retry_after.erase(file_name);
background_context.session.clear();
background_context.session_loaded_hash = "";
clear_shared_unit_cache(server_state);
usleep(250000);
continue;
}
@@ -1371,11 +1379,61 @@ void run_proactive_compiler()
}
}
void run_priority_compiler()
{
Request background_context;
background_context.server = &server_state;
set_active_request(background_context);
my_pid = getpid();
close_inherited_server_sockets();
signal(SIGSEGV, on_segfault);
signal(SIGABRT, on_segfault);
signal(SIGBUS, on_segfault);
signal(SIGILL, on_segfault);
signal(SIGFPE, on_segfault);
signal(SIGPIPE, SIG_IGN);
setpriority(PRIO_PROCESS, 0, 5);
while(!termination_signal_received)
{
auto units = compiler_take_priority_units(&background_context);
if(units.empty())
{
usleep(100000);
continue;
}
for(auto& file_name : units)
{
if(termination_signal_received)
break;
bool source_missing = false;
proactive_compile_unit(background_context, file_name, source_missing);
}
}
}
bool proactive_compiler_alive()
{
return(proactive_compiler_pid > 0 && task_kill(proactive_compiler_pid, 0) == 0);
}
pid_t spawn_compiler(const char* label, void (*runner)())
{
pid_t p = fork();
if(p < 0)
{
perror((String("fork ") + label).c_str());
return(0);
}
if(p == 0)
{
prctl(PR_SET_PDEATHSIG, SIGHUP);
runner();
exit(0);
}
printf("(P) %s spawned: PID %i\n", label, p);
return(p);
}
void ensure_proactive_compiler()
{
if(!to_bool(server_state.config["PROACTIVE_COMPILE_ENABLED"], true))
@@ -1383,24 +1441,10 @@ void ensure_proactive_compiler()
if(float_val(server_state.config["PROACTIVE_COMPILE_CHECK_INTERVAL"]) <= 0)
return;
if(proactive_compiler_alive())
return;
pid_t p = fork();
if(p < 0)
{
perror("fork proactive compiler");
return;
}
if(p == 0)
{
prctl(PR_SET_PDEATHSIG, SIGHUP);
run_proactive_compiler();
exit(0);
}
proactive_compiler_pid = p;
printf("(P) proactive compiler spawned: PID %i\n", p);
if(!proactive_compiler_alive())
proactive_compiler_pid = spawn_compiler("proactive compiler", run_proactive_compiler);
if(priority_compiler_pid <= 0 || task_kill(priority_compiler_pid, 0) != 0)
priority_compiler_pid = spawn_compiler("priority compiler", run_priority_compiler);
}
void listen_for_connections()
@@ -1557,6 +1601,8 @@ int main(int argc, char** argv)
{
if(!proactive_compiler_alive())
proactive_compiler_pid = 0;
if(priority_compiler_pid > 0 && task_kill(priority_compiler_pid, 0) != 0)
priority_compiler_pid = 0;
if(!termination_signal_received)
ensure_proactive_compiler();
@@ -1581,6 +1627,8 @@ int main(int argc, char** argv)
kill(worker.first, SIGTERM);
if(proactive_compiler_pid > 0)
kill(proactive_compiler_pid, SIGTERM);
if(priority_compiler_pid > 0)
kill(priority_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);