Skip to content

fix: bound the peer relay connection cache with LRU eviction - #202

Open
thexeos wants to merge 1 commit into
cloudflare:mainfrom
thexeos:fix/bound-remote-connection-cache
Open

fix: bound the peer relay connection cache with LRU eviction#202
thexeos wants to merge 1 commit into
cloudflare:mainfrom
thexeos:fix/bound-remote-connection-cache

Conversation

@thexeos

@thexeos thexeos commented Aug 13, 2026

Copy link
Copy Markdown

RemoteManager keeps one cached connection per (url, addr) peer and only drops an entry when that connection dies, so a relay that talks to many peers over its lifetime accumulates pooled QUIC connections without limit, each with its own keep-alive, for the life of the process. This adds a configurable capacity (default 256, 0 disables) with least-recently-used eviction, refreshing recency on cache hits as well as insertions. Eviction only reclaims connections that nothing is using — every caller holds a use guard while it is subscribed, publishing or forwarding over a connection, and an entry with a live guard (or a slot lock held by an in-flight connect) is skipped rather than closed, so a full pool of busy peers stays over capacity instead of cutting off a live subscription. No new dependencies; the LRU is a linear scan over a few hundred entries, run only when a new connection is added.

RemoteManager cached one connection per (url, addr) peer and only ever
dropped an entry when that connection died, so a relay that talks to many
peers over its lifetime accumulated pooled QUIC connections without limit —
each with its own keep-alive — for the life of the process.

Give the pool a configurable capacity (default 256, 0 disables) with
least-recently-used eviction. Recency is refreshed on cache hits as well as
insertion, and eviction only reclaims entries nothing is using: every caller
holds a use guard for as long as it is subscribed, publishing or forwarding
over that connection, and an entry with a live guard — or whose slot lock is
held by an in-flight connect or teardown — is skipped rather than closed, so
the pool may sit over capacity instead of cutting off a live subscription.
Candidate slots are probed with try_lock while the pool lock is held, so the
existing pool/slot lock order is unchanged and no lock is held across an
await.

RemoteManager::subscribe_namespace now returns the guard alongside the
SubscribeNamespace handle, since the handle outlives the call and would
otherwise leave the connection looking unused.
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.

1 participant