[T3 Connect] Reuse one HTTP client per replica for procedure requests - #6023
Draft
bradleyshep wants to merge 1 commit into
Draft
bradleyshep wants to merge 1 commit into
bradleyshep wants to merge 1 commit into
Conversation
bradleyshep
force-pushed
the
bradley/procedure-http-client-reuse
branch
from
September 30, 2026 17:23
01f2302 to
4de5d9c
Compare
2 of 3 tasks
bradleyshep
force-pushed
the
bradley/procedure-http-client-reuse
branch
from
September 30, 2026 17:45
4de5d9c to
f258cd6
Compare
`InstanceEnv::http_request` built a new reqwest client for every `ctx.http.fetch`, so no connection or TLS session was ever reused, and a module sending to an HTTP/2 service like APNs paid a full TCP and TLS handshake per request (the TODO(perf) this resolves). The client now lives on the ReplicaContext, built on first use and shared by the replica's module instances. It keeps the same DNS filter and redirect policy; per-request timeouts stay on the request. A failed build still surfaces as an HTTP error to the procedure and is retried on the next request.
bradleyshep
force-pushed
the
bradley/procedure-http-client-reuse
branch
from
October 1, 2026 17:26
f258cd6 to
d1a35f8
Compare
This branch has not been deployed
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.
Description of Changes
InstanceEnv::http_request(a procedure'sctx.http.fetch) built a newreqwest::Clientfor every request, so no connection or TLS session was ever reused (theTODO(perf)this resolves). A module that sends to an HTTP service repeatedly, such as Apple's push service, which recommends keeping connections open, paid a full TCP and TLS handshake per request.The client now lives on the
ReplicaContext, built on first use and shared by all of the replica's module instances, so their requests share one connection pool. It is dropped with the replica and survives module updates. Behaviour is otherwise unchanged:FilteredDnsResolver;A client that fails to build still surfaces as an HTTP error to the procedure, and the next request tries again.
The client is per replica rather than process-wide because a pooled connection belongs to the tokio runtime that opened it. Production runs procedure HTTP on one host runtime, but tests create a runtime per test.
Related: #6012 lets these requests negotiate HTTP/2. Together they give APNs a reused HTTP/2 connection.
API and ABI breaking changes
None.
Rollback safety impact
n/a
Expected complexity level and risk
Worth a reviewer's eye:
pool_idle_timeoutandpool_max_idle_per_hostcan be set inbuild_module_http_clientif needed.retry_canceled_requests, on by default); a request already sent when the server hung up fails like any other network error. reqwest drops idle connections after 90 s.Testing
http_requests_reuse_connection: two requests throughInstanceEnv::http_requestto a local keep-alive server arrive over one TCP connection. The test fails (2 connections) with the old per-request client.cargo test -p spacetimedb-core --lib --features allow_loopback_http_for_tests instance_env(23 passing), and without the feature (19)cargo clippy -p spacetimedb-core --all-targets: no new warningscargo fmt --checkcargo test --alldoesn't enableallow_loopback_http_for_testsfor core, so the loopback HTTP tests (this one and the existing decompression tests) never ran in CI.tools/ci/commands/testnow runs them in a focused step; the exact command runs 4 tests locally, and 5 with [T3 Connect] Negotiate HTTP/2 for procedure HTTPS requests #6012 applied too (its ALPN test included; all pass).instance_env.rs, so whichever merges second needs a trivial rebase (keep both tests).