From e22cbf8882f17e0d16f67ac7eacfe7c24978c133 Mon Sep 17 00:00:00 2001 From: udo Date: Mon, 20 Jul 2026 14:04:39 +0000 Subject: [PATCH] Close retained connectors on worker shutdown --- docs/setup.md | 3 +++ docs/wasm-runtime-architecture.md | 4 ++++ scripts/test_mysql_persistent_pool_idle.sh | 11 +++++++++++ src/wasm/backend.cpp | 6 ++++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/setup.md b/docs/setup.md index 988e0a1..39fd5c3 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -257,6 +257,9 @@ Important settings: 4 KiB positional read. Cache-miss full-artifact reads use the same checks around 64 KiB positional chunks. A single in-progress regular-file syscall cannot be cooperatively interrupted; later reads and parsing cannot overrun the budget. + Wasmtime's serialized-module deserialization call is also synchronous and + cannot be interrupted; if it stalls, the timeout is reported after that call + returns rather than at the nominal wall-clock boundary. Initial/final descriptor identity, unique selected metadata sections, and strict 64-bit LEB high-bit validation reject changed or ambiguous artifacts. diff --git a/docs/wasm-runtime-architecture.md b/docs/wasm-runtime-architecture.md index 2eb6d84..b3594ce 100644 --- a/docs/wasm-runtime-architecture.md +++ b/docs/wasm-runtime-architecture.md @@ -266,6 +266,10 @@ Cold module compilation and deserialization are host work, so `load_unit()` refreshes the epoch deadline before its first guest call. Otherwise a component whose compilation outlasted the guest CPU budget would immediately trap in the following allocator/relocation call even though no guest loop consumed it. +Wasmtime's serialized-module deserialization API is synchronous and has no +cooperative cancellation point. The absolute invocation timeout is checked +immediately after it returns, so a stalled deserialization may overrun the +nominal wall boundary before UCE reports the timeout. Unit artifacts live beneath an ABI-generation directory such as `BIN_DIRECTORY/units-c13-w7`: `c13` is the compiler/unit-metadata ABI and `w7` diff --git a/scripts/test_mysql_persistent_pool_idle.sh b/scripts/test_mysql_persistent_pool_idle.sh index 7ecbdae..bea1712 100755 --- a/scripts/test_mysql_persistent_pool_idle.sh +++ b/scripts/test_mysql_persistent_pool_idle.sh @@ -108,4 +108,15 @@ third=$(request /database.uce) IFS='|' read -r third_pid third_id third_source <<<"$third" [[ "$third_pid" == "$first_pid" && "$third_source" == "new" && "$third_id" != "$first_id" ]] +sleep 3 +plain=$(request /plain.uce) +[[ "$plain" == "$first_pid|plain" ]] +deadline=$((SECONDS + 5)) +while (( SECONDS < deadline )); do + connections=$(mariadb --batch --skip-column-names -e "SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE USER='$test_user'") + [[ "$connections" == "0" ]] && break + sleep 0.05 +done +[[ "$connections" == "0" ]] || { echo "final pooled fixture connection remained after idle eviction" >&2; exit 1; } + echo "Persistent MySQL idle eviction preserved hot reuse and retired the expired connection" diff --git a/src/wasm/backend.cpp b/src/wasm/backend.cpp index ffa23a4..84a8354 100644 --- a/src/wasm/backend.cpp +++ b/src/wasm/backend.cpp @@ -429,8 +429,8 @@ String wasm_backend_serve(Request& request, const String& entry_unit, const Stri return(""); } -// Stop the ticker before the worker process exits (best-effort; forked workers -// are usually killed, but a clean ager-out path should join the thread). +// Stop the ticker before destroying the worker state it references. Deleting +// the worker also closes retained connector resources on a clean process exit. void wasm_backend_shutdown() { if(g_wasm_epoch_ticker) @@ -441,4 +441,6 @@ void wasm_backend_shutdown() delete g_wasm_epoch_ticker; g_wasm_epoch_ticker = 0; } + delete g_wasm_worker; + g_wasm_worker = 0; }