Multi-session/connection support with a Worker-backed PGlite postmaster#1054
Draft
samwillis wants to merge 58 commits into
Draft
Multi-session/connection support with a Worker-backed PGlite postmaster#1054samwillis wants to merge 58 commits into
samwillis wants to merge 58 commits into
Conversation
|
Looking forward to trying this out! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multi-session/connection support
This PR adds an opt-in, Node-only architecture for running PGlite with PostgreSQL's normal postmaster and multiple real backend sessions. It is the first implementation of multi-session/connection support: concurrent clients get independent PostgreSQL backends, transaction state, session state, locks, notifications, cancellation, and protocol connections rather than multiplexing requests through the existing single-user runtime.
The existing
PGliteconstructor and classic single-user Wasm artifact remain available and unchanged as a separate runtime. The new architecture is selected explicitly withPGlitePostmaster.create(), and sessions expose the normal PGlite interface.Architecture
PostgreSQL processes mapped to Workers
EXEC_BACKENDprocess-start path, analogous to the non-fork()model used on Windows. Backends and auxiliary processes start cleanly and reattach to shared cluster state.SharedArrayBuffers andAtomics.wait/notifywithout unwinding active Wasm stacks.Multi-memory model
The postmaster build separates PostgreSQL address-space lifetimes into three Wasm memory domains:
The build retains PostgreSQL's 32-bit C pointers using a tagged memory32 ABI. A pinned Binaryen post-link transformer rewrites scalar, SIMD, bulk-memory, and atomic memory operations to the correct Wasm memory. Pointer-provenance analysis specializes known-private and known-shared accesses, while a sound generic dispatch remains for unknown provenance. Host calls decode tagged pointers through the PGlite libc boundary.
All compiler, transformer, auditor, archive, and wrapper-generation tooling runs in the pinned Docker build image. The currently qualified builder path is native Linux ARM64.
Connections, server, and filesystem
PGliteInterfacesurface.@electric-sql/pglite-serverprovides the Node TCP/Unix-socket orchestration layer, and thepglitedistribution exposesinitdb,server/postgres,psql, dump/restore, and administration commands.Extension artifacts
Native extensions are selected by an explicit runtime target rather than loading the nearest compatible-looking module. The forward-compatible matrix covers pointer width and memory topology, while this PR completes only the
wasm32-initialprofile:wasm32-classicwasm32-multi-memoryArtifacts have generated descriptors, manifests, ABI identities, hashes, bounded archive extraction, atomic publication, lifecycle hooks, dependency/preload ordering, and actual-Wasm validation. Dynamic side modules are transformed and audited at build time; no client-side Wasm rewriting is required. Vector and PostGIS are the initial qualified extension inventory.
What is implemented
PGlitePostmaster.create()and normal PGlite-compatible session objects.EXEC_BACKENDstartup and parameter transport.LISTEN/NOTIFY, COPY, and connection churn coverage.make checkandmake check-world, with an explicit capability ledger for unsupported and blocked upstream cases.postgres-pglitecommit containing the minimal fork-side build and PGlite-libc changes.Validation
check-worldclusters: 185/185 passed, with zero supported failures.wasm32-initialrelease validation passed for Vector and PostGIS; combined compressed artifacts are 43,408,184 bytes and remain below the frozen 48 MiB budget.The upstream capability ledger is intentional and visible, but it records test qualification rather than declaring every blocked feature architecturally absent. PostgreSQL crash recovery and WAL replay after a forced Worker failure are implemented and tested. WAL sender/receiver, logical-replication workers, recovery code, and replication protocol paths are present in the generic
EXEC_BACKENDprocess model; parts of physical backup, logical decoding, and recovery may already work. The complete multi-cluster physical/logical replication, subscription, standby promotion, archive recovery, and PITR workflows have not yet been qualified end to end. Their current blockers include backend outbound connections to another postmaster, multi-cluster test orchestration, and host-command execution for conventionalarchive_command/restore_commandworkflows.pg_upgradeand tests which require real OS child PIDs remain genuinely unsupported by the current artifact/provider. One libpq test which launches three complete postmasters is recorded as blocked because it exceeds Docker Desktop's 7.65 GiB VM memory limit; supported libpq behavior passes.What is not implemented
@electric-sql/pglite; this implementation phase is Node-only.SharedArrayBufferbut do not provide Wasm multi-memory. Those environments are not supported byPGlitePostmasterin this PR, but the target identity, extension matrix, and fallback selection model reserve this route.wasm32-classicandwasm32-multi-memory, and only Vector/PostGIS are in the initial postmaster extension inventory.archive_command/restore_commandexecution.pg_ctlcreate/start/status/reload/restart/stop flows and many native client utilities pass. Operations tied specifically to host child PIDs, a forked logging collector, multiple PostgreSQL binary versions (pg_upgrade), or direct host signals remain unsupported or require provider-specific handling.Design documents
multi-session-worker-multi-memory-design.mddescribes the postmaster, Worker process model, memory domains, pointer ABI, signals, scopes, sockets, VFS, testing, and implementation phases.multi-runtime-extension-artifacts-design.mddefines the multi-runtime extension target matrix, manifests, wrapper and lifecycle contracts, safe materialization, build pipeline, and the completedwasm32-initialmilestone.This is a large architectural proof and is intentionally opened as a draft for review of the execution model, memory ABI, PostgreSQL-fork boundary, and the path from the current Node/ARM64 qualification to broader runtime support.