Skip to content

fix(wasix): deep-recursion recovery consolidated into #201 #265

Closed as not planned

Description

@f0rr0

Consolidated into #201

The deep-recursion SQL recovery defect remains unresolved. This issue is closed only to remove duplicate tracking. Its implementation, original workload matrix, stack-boundary requirements and recovery acceptance are owned by #201, Deep recursion and SQL recovery.

The reproduction, frozen package identity, SQL fixtures, Windows/Linux results and PGlite comparison are preserved below. #208 remains the closed backend-selection decision; #266 owns performance. Fixes must still prove reusable SQL recovery on supported packaged engines, not merely catch terminal traps or lower max_stack_depth.

Deep-recursion reproduction, exact artifacts and original acceptance

Historical snapshot before consolidation. Current ownership is defined above and in #203. Statements about old owners, branch state and old proposed policy below are not the active backlog. Historical checkboxes have been retired; the evidence and acceptance detail are retained.

Status reconciliation — 8 October 2026

Still open: the demonstrated deep-recursion recovery defect has not been fixed by the dependency refresh or successful package CI. Reviewed main 293f31f4 and #218 3b1f7cd4. #255 and #247 are merged into #218; #218 is not merged into main. #208 correctly remains closed as the backend decision.

The reproduction below is tied to frozen 8db3bd88 packages and explicitly all-on directory settings. #268 now changes the integration candidate's embedded boot default to fsync off; that policy change is not a recursion repair. Rerun the original workload matrix on the final candidate and record effective GUCs, retaining an explicit-on directory control. Do not mix old all-on results with new-default performance evidence or treat terminal-fault containment as reusable SQL recovery. Historical JSON regression work in #204 is related context, not proof of the same root cause or a fix for these fixtures.

Problem

Deep SQL recursion can exhaust the Wasm engine's execution stack before PostgreSQL reports a recoverable depth error. The packaged desktop WASIX runtime then retires the database session, and subsequent queries fail. This affects the tested Windows V8 and Linux Sys paths; it is not just the original Windows/MSVC exception-handling defect.

Split from #208. The supported Windows V8 work from #255 merged through #247 into the still-open #218. This issue owns the remaining recursion correctness requirement.

Reproduction and evidence

Native Windows run 37711318785 reused the actual packages from successful source run 37584874208, source SHA 8db3bd8885c32a5ca546f9038fc04764ab56610b. The isolated probe records binary/fixture hashes, phases, SQLSTATEs, subsequent-query outcomes and process exits. Results are retained in the run's deep-recursion-windows-x64-msvc artifact. A local Linux control used the corresponding package from the same source run.

Each host ran 40 cases: direct/actor APIs × memory/directory storage × default/100 kB stack limits × five workloads. Directory tests retained fsync, synchronous_commit and full_page_writes all on.

  • Default max_stack_depth=2MB: 0/20 cases recovered on either host.
  • Diagnostic 100kB: 8/20 recovered on either host. Expressions and PL/pgSQL passed repeated reuse, savepoint rollback, guest exception handling where applicable, and directory reopen; all three JSON workloads still failed.
  • Failing calls returned a runtime error without a PostgreSQL SQLSTATE. The next SELECT 42 was rejected because session state was unknown. No test process crashed or timed out; this is a demonstrated SQL recovery gap, not a claim that terminal-fault containment failed.

Fixtures:

SELECT repeat('[', 10000)::json;
SELECT repeat('{"a":', 10000)::json;
SELECT length((repeat('[', 10000) || '0' || repeat(']', 10000))::json::text);

The other fixtures are a SELECT expression with 5,000 additions and a PL/pgSQL function recursively calling itself to requested depth 2,000. Their definitions are in the linked probe.

PGlite 0.5.8 comparison run 37712671927 also failed these workloads through its public exec/query APIs on Windows and Linux. It sometimes returned empty/missing results after swallowing an execution-stack exception. Borrowing that behavior is not a fix. Its separate ordinary-error stack-budget leak is tracked upstream in PGlite #1115.

Direction and acceptance

  • Trace the original engine cause on exact packaged inputs before choosing the repair; the public N-API error currently retains only outer context. Establish a proven safety boundary for both guest shadow-stack and engine execution-stack use. The existing 8 MiB guest stack alone does not establish execution-stack headroom. Wasmer #6994 tracks the underlying stack-budget concern; the experimental Sys remaining_execution_stack() API is not a V8 measurement.
  • Implement the smallest shared runtime/guest solution that produces a correct result or a recoverable PostgreSQL error before exhausting either stack. A correct syntax error for malformed JSON is acceptable; silently lost results are not. Lowering the GUC alone is disproved as a complete remedy. Preserve existing SDK APIs and normal installation; consumers must not need Windows-only flags, compilation, or recovery workarounds.
  • Verify repeated query reuse, transaction/savepoint rollback, PL/pgSQL exception-block rollback, committed-data preservation, close/reopen, and restoration of settings with the original fixtures and meaningful boundary cases. Validate caller-selected max_stack_depth through the existing configuration contract.
  • Promote a minimal regression subset into existing product-owned SQL recovery tests and CI. Exercise Rust sync/async and relevant N-API direct/actor/worker consumers; prove Windows V8 and Linux/macOS non-regression against supported artifacts. State untested browser/Postmaster scope explicitly.
  • Preserve terminal handling for genuine engine traps, host panics and untrustworthy session state. Do not re-enter a failed guest, retry SQL, implicitly reopen a database, weaken durability, or relabel a caught trap as successful SQL recovery. Record the measured ordinary-query overhead of the chosen guard.

Done means reusable SQL recovery on the supported desktop runtime, with actual packaged execution evidence. Ordinary exception tests or a larger stack allocation alone do not close this issue. Carry any required downstream patch through the existing owned source/patch/release pipeline.

Activity

  1. added
    bugSomething isn't working
    rustPull requests that update rust code
    on Oct 8, 2026
  2. changed the title [-]fix(wasix): preserve SQL recovery for deep recursion on desktop[/-] [+]fix(wasix): deep-recursion recovery consolidated into #201[/+] on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrustPull requests that update rust code

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions