mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-14 22:21:24 +00:00
The Postgres driver is async but the Python-facing API will be synchronous, so we need a way to drive tokio futures to completion from a sync, GIL-holding method. Add a process-global, lazily-initialised multi-thread tokio runtime (`database::runtime`) whose worker threads only drive the connection tasks: the actual blocking wait happens on the calling Python thread, so a small fixed pool can't starve itself. Add the `block_on` / `block_on_result` / `block_on_next` extension traits (`database::postgres::helpers`) that block on that runtime while releasing the GIL (`py.detach`), so other Python threads keep running while we wait. `pg_err_to_py` maps a driver error into a Python `RuntimeError`. `BlockingPostgresStream` is implemented generically over `Pin<&mut Fuse<S>>` rather than just `RowStream`. This is deliberate: it lets the cursor state machine added in the next change be unit-tested against an in-memory fake stream, with no live database. The module doc spells out why polling a `RowStream` off the runtime (the non-blocking fast path) is sound, and why the `Fuse` bound is required rather than merely assumed. These modules are `pub` for now so the not-yet-consumed items don't trip clippy's `dead_code` lint; later changes tighten that. Unit tests cover the ready / pending / exhausted stream paths (using an in-memory stream and a `yield_now`-based pending future) and the runtime's shared-instance behaviour. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>