Skip to content

worldtree: multiplex per-zone source reads over a bounded connection …#40

Closed
sonkehahn-shopify wants to merge 1 commit into
Shopify:worldtreefrom
sonkehahn-shopify:river-worldtree-connection-pool
Closed

worldtree: multiplex per-zone source reads over a bounded connection …#40
sonkehahn-shopify wants to merge 1 commit into
Shopify:worldtreefrom
sonkehahn-shopify:river-worldtree-connection-pool

Conversation

@sonkehahn-shopify

@sonkehahn-shopify sonkehahn-shopify commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

superseded by #41, closing.

Motivation

worldtreed has a connection limit (512) and for bigger evals tecnix runs over that limit. This PR multiplexes connections through a connection pool of size 64.

Changes

The socket-served source path (Mode B, tec --sha) opened a fresh WorldtreeConn per clean zone in EvalState::getZoneStorePath, each hosting one scoped ephemeral RO session. A hard cap on concurrent connections can't fix this — the planner needs more zones mounted at once than any safe per-listener cap allows. But the daemon already supports many ephemeral RO sessions per connection: its owned_ephemeral set is per-connection and is drained on disconnect (wt-controlplane/src/rpc/server.rs). So this multiplexes the per-zone sessions over a bounded pool:

  • WorldtreeConn gains a ws-parametric API (openScopedSession, closeSessionOn, readTreeOn, readBlobOn) so one physical connection can host many independent per-zone sessions. The existing single-session methods (used by the singleton control connection) are untouched.
  • New WorldtreeZoneSession handle owns one zone's scoped session on a shared carrier connection and releases it (close_ro) when the zone's WorldtreeSourceAccessor — its sole owner — drops.
  • EvalState::acquireWorldtreeZoneSession draws a carrier round-robin from a lazily-grown pool bounded by the new tectonix-worldtree-max-connections setting (default 64, well under 512), and opens the zone's scoped session on it. getZoneStorePath uses it instead of one connection per zone.

Design notes / tradeoffs:

  • Confinement is unchanged. Each zone still gets its own scoped session; the daemon enforces the cone per session, independent of which connection hosts it.
  • Concurrency. Reads that land on the same carrier serialize on that connection's mutex; cross-zone parallelism now comes from the pool holding several carriers (default 64 ≥ typical core counts) rather than one connection per zone.
  • Lock ordering. acquireWorldtreeZoneSession never calls a carrier's client under the pool mutex — the open_ro happens after the pool lock is released — so there is no pool-mutex/carrier-mutex inversion.
  • Fail-loud preserved. Growing the pool uses connectWorldtree(), which throws on an unreachable daemon (no libgit2 fallback).

…pool

The socket-served source path (Mode B, `tec --sha`) opened one worldtree
control-socket connection per clean zone in `getZoneStorePath`. A broad
evaluation — the Tartarus planning bundle over a large changeset, run with
parallel-eval + `eval-cores 0` — fans out to hundreds of zones at once, so it
opened >512 connections in a burst and tripped worldtreed's per-listener
connection cap (`ServeConfig::max_connections`, 512). Past the cap the daemon
accepts-then-drops, which the C++ client sees as
`worldtree: read(): Connection reset by peer`, aborting the eval.

A hard cap on concurrent connections cannot fix this: the planner needs more
zones mounted simultaneously than any safe per-listener cap allows. The daemon
already supports many ephemeral RO sessions per connection (its owned-ephemeral
set is per-connection and is drained on disconnect), so instead multiplex the
per-zone scoped sessions over a bounded pool of connections.

- `WorldtreeConn` gains a ws-parametric API (`openScopedSession`,
  `closeSessionOn`, `readTreeOn`, `readBlobOn`) so one physical connection can
  host many independent per-zone sessions; the existing single-session methods
  (used by the control connection) are unchanged.
- New `WorldtreeZoneSession` handle owns one zone's scoped session on a shared
  carrier connection and releases it (`close_ro`) when the zone's
  `WorldtreeSourceAccessor` — its sole owner — drops.
- `EvalState::acquireWorldtreeZoneSession` draws a carrier round-robin from a
  lazily-grown pool bounded by the new `tectonix-worldtree-max-connections`
  setting (default 64, well under the daemon's 512 cap), and opens the zone's
  scoped session on it. `getZoneStorePath` uses it instead of one connection
  per zone.

Per-zone confinement is unchanged: each zone still gets its own `scoped`
session (the daemon enforces the cone per session), just hosted on a shared
connection. Reads that land on the same carrier serialize on it; cross-zone
parallelism now comes from the pool holding several carriers rather than one
connection per zone.

Co-authored-by: Sonke Hahn <sonke.hahn@shopify.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants