diff --git a/docs/wasm-runtime-architecture.md b/docs/wasm-runtime-architecture.md index e3c4a9a..5292659 100644 --- a/docs/wasm-runtime-architecture.md +++ b/docs/wasm-runtime-architecture.md @@ -137,6 +137,11 @@ own import vector, memory/table-base globals, GOT globals and function-table slots, then runs relocations, constructors, and request-pointer binding. This removes repeated Wasmtime import-type traversal without sharing request state or changing core-first, unit-load-order symbol resolution. +Each FastCGI child initializes its process-local Wasmtime engine after fork and +before entering the accept loop. This preserves Wasmtime's fork boundary while +preventing the first request assigned to each worker from paying engine startup. +Startup duration or failure is written to the service log. + `request_perf()` reports worker module-cache hits and misses and divides a miss into artifact lookup, wasm read, custom-section parse, serialized-module deserialization or wasm compilation, and immutable import classification. This diff --git a/src/linux_fastcgi.cpp b/src/linux_fastcgi.cpp index 9e98eb3..5eb9d62 100644 --- a/src/linux_fastcgi.cpp +++ b/src/linux_fastcgi.cpp @@ -1388,6 +1388,15 @@ void listen_for_connections() server.on_data = &handle_data; server.on_complete = &handle_complete; server.on_cli_complete = &handle_cli_complete; + Request startup_context; + startup_context.server = &server_state; + f64 wasm_start = time_precise(); + String wasm_error = wasm_backend_start(startup_context); + f64 wasm_ms = (time_precise() - wasm_start) * 1000.0; + if(wasm_error == "") + 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(;;) { server.process(-1); diff --git a/src/wasm/backend.cpp b/src/wasm/backend.cpp index 0ecb92c..9cd2994 100644 --- a/src/wasm/backend.cpp +++ b/src/wasm/backend.cpp @@ -88,6 +88,11 @@ static String wasm_backend_ensure_started(Request* context) return(""); } +String wasm_backend_start(Request& request) +{ + return(wasm_backend_ensure_started(&request)); +} + static bool wasm_artifact_exists(Request* context, const String& entry_unit) { if(entry_unit == "") diff --git a/src/wasm/backend.h b/src/wasm/backend.h index 0f1e440..84f3489 100644 --- a/src/wasm/backend.h +++ b/src/wasm/backend.h @@ -10,6 +10,10 @@ // artifact; handler-agnostic, the caller names the handler. bool wasm_backend_should_handle(Request& request, const String& entry_unit); +// Initialize the process-local engine after fork and before the worker accepts +// requests. Returns "" on success or the retained backend initialization error. +String wasm_backend_start(Request& request); + // Serve a request through a wasm workspace by invoking a named unit handler — // "render", "cli", "websocket", "serve_http", "serve_http:named" — and populate // the native Request. Returns "" on success or a collapsed error. The handler is