Avoid repeated warm request dispatch work

This commit is contained in:
udo 2026-07-18 02:32:28 +00:00
parent 72fd0dd53a
commit 339031b6c3
4 changed files with 26 additions and 5 deletions

View File

@ -152,6 +152,11 @@ host imports into a store-independent Wasmtime `InstancePre`, and births then
drops one empty workspace. This preserves Wasmtime's fork boundary while
preventing the first request assigned to each worker from paying engine, linker,
or pre-instantiation startup.
Server configuration is immutable by that point. The worker therefore retains
one native `DValue` view of it; each request's temporary context tree references
that view while UCEB is encoded, avoiding a repeated native tree copy. The guest
still decodes the bytes into its fresh request tree. Request parameters, body,
cookies, session, call data, and response state are never retained this way.
Startup duration or failure is written to the service log. The serialized core
module lives in the configured writable cache root rather than beside the
possibly root-owned deployed `core.wasm`; freshness still uses the deployed
@ -260,6 +265,12 @@ module cache, adding a visible cold-start request. Request state remains bounded
by the fresh workspace and the normal per-request database/resource cleanup;
faulted workers still exit and are replaced by the parent.
A warm entry artifact is checked for compiler/source freshness once before
dispatch. A missing or stale artifact is compiled (or demand-prioritized) and
then checked again before execution. The second check belongs only to that
state-changing branch; repeating it immediately after a successful warm check
adds no freshness guarantee.
The request context remains UCEB2 so application `context.call` semantics do
not fork into a private transport type. Validated decode trees move into the
request rather than being deep-copied twice; the historical by-value

View File

@ -439,9 +439,13 @@ int handle_cli_complete(FastCGIRequest& request)
// been removed, so a unit that still cannot be served by wasm is a
// request failure instead of a fallback path.
SharedUnit* cli_compile_state = 0;
if(!wasm_backend_should_handle(request, cli_unit))
bool cli_wasm_ready = wasm_backend_should_handle(request, cli_unit);
if(!cli_wasm_ready)
{
cli_compile_state = get_shared_unit(&request, cli_unit);
if(wasm_backend_should_handle(request, cli_unit))
cli_wasm_ready = wasm_backend_should_handle(request, cli_unit);
}
if(cli_wasm_ready)
{
String wasm_error = wasm_backend_serve(request, cli_unit, "cli");
if(wasm_error != "")
@ -596,8 +600,9 @@ int handle_complete(FastCGIRequest& request) {
// be served by wasm becomes a clean 500 request failure.
SharedUnit* entry_compile_state = 0;
auto wasm_ready = [&](const String& unit) -> bool {
if(!wasm_backend_should_handle(request, unit))
entry_compile_state = get_shared_unit(&request, unit);
if(wasm_backend_should_handle(request, unit))
return(true);
entry_compile_state = get_shared_unit(&request, unit);
return(wasm_backend_should_handle(request, unit));
};
auto fail_wasm_unavailable = [&](const String& handler) {

View File

@ -68,6 +68,10 @@ static String wasm_backend_ensure_started(Request* context)
}
g_wasm_worker = new WasmWorker(wc);
// Server configuration is finalized before render workers start. Retain one
// native tree so per-request UCEB encoding can reference it without rebuilding
// dozens of identical nodes; the guest still decodes it into fresh state.
g_wasm_worker->server_config_context = cfg;
g_wasm_init_error = g_wasm_worker->init();
if(g_wasm_init_error == "")
g_wasm_init_error = wasm_worker_prepare(*g_wasm_worker);
@ -156,7 +160,7 @@ String wasm_backend_serve(Request& request, const String& entry_unit, const Stri
ctx[key][entry.first] = entry.second;
};
if(request.server)
copy_map(request.server->config, "server_config");
ctx["server_config"].set_reference(&g_wasm_worker->server_config_context);
copy_map(request.params, "params");
copy_map(request.get, "get");
copy_map(request.post, "post");

View File

@ -973,6 +973,7 @@ public:
std::optional<wasmtime::Module> core_module;
std::optional<wasmtime::Linker> core_linker;
std::unique_ptr<wasmtime_instance_pre_t, WasmInstancePreDeleter> core_instance_pre;
DValue server_config_context;
struct CoreImport
{
String module;