Avoid repeated warm request dispatch work
This commit is contained in:
@@ -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
|
drops one empty workspace. This preserves Wasmtime's fork boundary while
|
||||||
preventing the first request assigned to each worker from paying engine, linker,
|
preventing the first request assigned to each worker from paying engine, linker,
|
||||||
or pre-instantiation startup.
|
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
|
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
|
module lives in the configured writable cache root rather than beside the
|
||||||
possibly root-owned deployed `core.wasm`; freshness still uses the deployed
|
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;
|
by the fresh workspace and the normal per-request database/resource cleanup;
|
||||||
faulted workers still exit and are replaced by the parent.
|
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
|
The request context remains UCEB2 so application `context.call` semantics do
|
||||||
not fork into a private transport type. Validated decode trees move into the
|
not fork into a private transport type. Validated decode trees move into the
|
||||||
request rather than being deep-copied twice; the historical by-value
|
request rather than being deep-copied twice; the historical by-value
|
||||||
|
|||||||
@@ -439,9 +439,13 @@ int handle_cli_complete(FastCGIRequest& request)
|
|||||||
// been removed, so a unit that still cannot be served by wasm is a
|
// been removed, so a unit that still cannot be served by wasm is a
|
||||||
// request failure instead of a fallback path.
|
// request failure instead of a fallback path.
|
||||||
SharedUnit* cli_compile_state = 0;
|
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);
|
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");
|
String wasm_error = wasm_backend_serve(request, cli_unit, "cli");
|
||||||
if(wasm_error != "")
|
if(wasm_error != "")
|
||||||
@@ -596,8 +600,9 @@ int handle_complete(FastCGIRequest& request) {
|
|||||||
// be served by wasm becomes a clean 500 request failure.
|
// be served by wasm becomes a clean 500 request failure.
|
||||||
SharedUnit* entry_compile_state = 0;
|
SharedUnit* entry_compile_state = 0;
|
||||||
auto wasm_ready = [&](const String& unit) -> bool {
|
auto wasm_ready = [&](const String& unit) -> bool {
|
||||||
if(!wasm_backend_should_handle(request, unit))
|
if(wasm_backend_should_handle(request, unit))
|
||||||
entry_compile_state = get_shared_unit(&request, unit);
|
return(true);
|
||||||
|
entry_compile_state = get_shared_unit(&request, unit);
|
||||||
return(wasm_backend_should_handle(request, unit));
|
return(wasm_backend_should_handle(request, unit));
|
||||||
};
|
};
|
||||||
auto fail_wasm_unavailable = [&](const String& handler) {
|
auto fail_wasm_unavailable = [&](const String& handler) {
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ static String wasm_backend_ensure_started(Request* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_wasm_worker = new WasmWorker(wc);
|
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();
|
g_wasm_init_error = g_wasm_worker->init();
|
||||||
if(g_wasm_init_error == "")
|
if(g_wasm_init_error == "")
|
||||||
g_wasm_init_error = wasm_worker_prepare(*g_wasm_worker);
|
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;
|
ctx[key][entry.first] = entry.second;
|
||||||
};
|
};
|
||||||
if(request.server)
|
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.params, "params");
|
||||||
copy_map(request.get, "get");
|
copy_map(request.get, "get");
|
||||||
copy_map(request.post, "post");
|
copy_map(request.post, "post");
|
||||||
|
|||||||
@@ -973,6 +973,7 @@ public:
|
|||||||
std::optional<wasmtime::Module> core_module;
|
std::optional<wasmtime::Module> core_module;
|
||||||
std::optional<wasmtime::Linker> core_linker;
|
std::optional<wasmtime::Linker> core_linker;
|
||||||
std::unique_ptr<wasmtime_instance_pre_t, WasmInstancePreDeleter> core_instance_pre;
|
std::unique_ptr<wasmtime_instance_pre_t, WasmInstancePreDeleter> core_instance_pre;
|
||||||
|
DValue server_config_context;
|
||||||
struct CoreImport
|
struct CoreImport
|
||||||
{
|
{
|
||||||
String module;
|
String module;
|
||||||
|
|||||||
Reference in New Issue
Block a user