feat: request_perf() worker-side timing hostcall; restore demo System Info

Units run in the wasm sandbox, so my_pid/parent_pid/context.server->request_count
read as sandbox stubs — the demo System Info counters were broken, and there was
no authoritative server-side request timing available to unit code (client-side
measurement cannot see queue/dispatch latency).

Add a request_perf() unit API backed by a new uce_host_request_perf hostcall.
The native worker answers it live, returning a DValue:
  worker_pid, parent_pid, request_count,
  accept_us  = (time_start - time_init)*1e6   (entry -> dispatch wait),
  running_us = (now - time_start)*1e6         (since dispatch, live),
  total_us   = (now - time_init)*1e6          (since the request entered UCE),
  workspace_birth_us.
time_init is captured at request entry (handle_request, with a handle_complete
fallback); a RequestPerfSnapshot {pids, request_count, time_init, time_start} is
threaded from wasm_backend_serve through wasm_worker_serve onto the workspace,
and the hostcall computes the live deltas at call time. Wired like uce_host_units
(sized DValue hostcall): core_hostcalls.syms + sys.cpp/sys.h request_perf().

site/demo/index.uce System Info now uses request_perf() and shows the real worker
PID, an incrementing per-worker request count, and the timing counters.

Implemented via the pi agent (gpt-5.3-codex-spark); a review of the live numbers
caught accept_us mistakenly computed as (now - time_init) (== total_us), fixed to
the dispatch wait (time_start - time_init). Independently verified on the host:
System Info shows non-zero PIDs, incrementing count, accept_us ~50us << total_us
~2.4ms with accept+running==total; run_cli_tests --include-wasm-kill => 87 passed,
0 failed, 0 skipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-15 08:18:04 +00:00
co-authored by Claude Opus 4.8
parent 83ab9e10f7
commit 4f84ac544d
7 changed files with 94 additions and 15 deletions
+50 -4
View File
@@ -404,10 +404,30 @@ public:
u64 component_resolve_count = 0;
u64 component_resolve_total_us = 0;
struct RequestPerfSnapshot
{
u64 worker_pid = 0;
u64 parent_pid = 0;
u64 request_count = 0;
f64 time_init = 0;
f64 time_start = 0;
bool active = false;
} request_perf;
explicit WasmWorkspace(WasmWorker& w) : worker(w), store(w.engine)
{
}
void set_perf_snapshot(u64 worker_pid, u64 parent_pid, u64 request_count, f64 time_init, f64 time_start)
{
request_perf.worker_pid = worker_pid;
request_perf.parent_pid = parent_pid;
request_perf.request_count = request_count;
request_perf.time_init = time_init;
request_perf.time_start = time_start;
request_perf.active = true;
}
#ifdef UCE_WASM_HOST_CONNECTORS
// Host-owned resource handle table (§3.1): connections opened by the guest
// live here and are closed when the workspace drops at request end.
@@ -1221,9 +1241,33 @@ private:
}));
if(mod == "env" && name == "uce_host_time_precise")
return(add([](Caller, Span<const Val>, Span<Val> results) -> Result<std::monostate, Trap> {
struct timeval tv;
gettimeofday(&tv, 0);
results[0] = Val((double)tv.tv_sec + (double)tv.tv_usec / 1e6);
results[0] = Val(time_precise());
return(std::monostate());
}));
if(mod == "env" && name == "uce_host_request_perf")
return(add([self](Caller, Span<const Val> args, Span<Val> results) -> Result<std::monostate, Trap> {
DValue response;
if(self->request_perf.active)
{
f64 now = time_precise();
response["worker_pid"] = (f64)self->request_perf.worker_pid;
response["parent_pid"] = (f64)self->request_perf.parent_pid;
response["request_count"] = (f64)self->request_perf.request_count;
if(self->request_perf.time_start > 0 && self->request_perf.time_init > 0)
response["accept_us"] = (f64)((self->request_perf.time_start - self->request_perf.time_init) * 1000000.0);
if(self->request_perf.time_start > 0)
response["running_us"] = (f64)((now - self->request_perf.time_start) * 1000000.0);
if(self->request_perf.time_init > 0)
response["total_us"] = (f64)((now - self->request_perf.time_init) * 1000000.0);
if(self->workspace_birth_us > 0)
response["workspace_birth_us"] = (f64)self->workspace_birth_us;
}
String encoded = ucb_encode(response);
u32 cap = (u32)args[3].i32();
int32_t buf = args[2].i32();
if(buf != 0 && cap >= encoded.size())
self->hostcall_write(buf, encoded);
results[0] = Val((int32_t)encoded.size());
return(std::monostate());
}));
if(mod == "env" && name == "uce_host_env")
@@ -1898,10 +1942,12 @@ private:
// ---- public entry: one request through one workspace -----------------------
inline WasmResponse wasm_worker_serve(WasmWorker& worker, const DValue& context_tree, const String& entry_source_path,
const String& handler = "render")
const String& handler = "render", const Request* request = 0)
{
WasmResponse response;
WasmWorkspace workspace(worker);
if(request)
workspace.set_perf_snapshot(my_pid, (u64)parent_pid, request->server ? request->server->request_count : 0, request->stats.time_init, request->stats.time_start);
auto birth_start = std::chrono::steady_clock::now();
String error = workspace.birth();
workspace.workspace_birth_us = (u64)std::chrono::duration_cast<std::chrono::microseconds>(