Repository navigation
fix: prevent SQS connection churn and blocking DNS - #929
Conversation
|
Enclave skipped this draft pull request. It will run automatically when you mark the PR as Ready for review. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
|
@greptileai review the current head |
|
Real AWS / Linux ARM64 validation of f5b9293 is in progress. The transport changes materially reduce connection churn and keep Tokio at seven threads, but I cannot yet call the mixed HTTP + SQS workload fully fixed. With a standalone Bun 1.4.2 executable, seven serving Workers, a seven-CPU limit, two receivers × four long polls, 400 pending messages per receiver, individual acknowledgments, a nonempty real SQS backlog, and 15,000 HTTP requests/second:
The current HTTP handler deliberately repeats SQLite reads and JSON parsing to calibrate CPU load; it is heavier than a cached application handler. I am now validating the actual cached-handler / routed-write flow with synthetic data before drawing a workload-specific conclusion. No debugger-attached run is included in the numbers above. The accepted-response body-read error is correctly non-retryable, preserving the distinction between a failed response read and a mutation that is safe to replay. The body-drain, burst reuse, and no-replay tests were also rerun successfully. |
|
Completed real AWS mixed-load validation of f5b9293 using a compiled Bun 1.4.2 Linux ARM64 application, seven Workers, individual SQS acknowledgements, and synthetic data. The native baseline reproduced the sustained regression: Tokio threads reached 98, mean CPU fell to 2.70 cores, and achieved HTTP throughput fell to 5,648 RPS. This PR kept Tokio at seven threads and restored both HTTP and queue throughput. The final ten-minute repeat, with default runtime settings, served 9,000,090 requests at 15,000 RPS while processing approximately 1,503 push attempts/sec. Independent AWS metrics confirmed approximately 1,503 queue deletions/sec. There were no restarts, receive/ack warnings, or CPU throttling. All 11,394 timeouts and 43 overloads occurred in the first 30 seconds. The next 570 seconds served 8,550,085 requests with zero timeouts or overloads and one connection reset; per-window p99 was at most 201 ms. A separate six-minute repeat likewise had no timeouts or overloads after its first 30 seconds. The SDK reference also showed startup failures, while processing substantially fewer queue messages. The receiver rewrite failed load acceptance and was discarded. GC/JIT overrides did not establish a repeatable complete improvement and are not part of the fix. The existing transport change is the supported fix for the sustained regression; these results do not establish a zero-error cold-start guarantee or correctness for every future workload. The original dataset/load command was unavailable, so this is a controlled realistic reproduction. PR validation details are updated accordingly. |
alongubkin
left a comment
There was a problem hiding this comment.
Validated the exact head on real AWS/Linux ARM64 in a compiled Bun 1.4.2 application. The baseline reproduced thread growth and sustained throughput collapse; the fixed build sustained 15k HTTP RPS and approximately 1.5k independently measured SQS deletions/sec across a ten-minute repeat, with seven Tokio threads and no receive/ack warnings or restarts. The transport change and nonretryable successful-header body-read error handling are correct for this regression. Startup HTTP failures remain and are documented; no zero-error cold-start guarantee is implied. No additional receiver or runtime-flag change is justified by the tests.
AWS-enabled SDK consumers inherit hickory-proto 0.25.2 through the SQS resolver added in #929. Dependency audits reject RUSTSEC-2026-0118 and RUSTSEC-2026-0119. Use the patched 0.26 series (minimum 0.26.1; lockfile resolves 0.26.3) and propagate resolver-construction errors introduced by its fallible builder. Preserve system DNS configuration, the asynchronous per-client resolver, IPv4/IPv6 lookup strategy, TTL caching, the bounded idle pool and successful-response draining. No other transport or DNS service is changed. Validation in a Linux sandbox: - A standalone AWS/local/Worker SDK consumer fails cargo-deny with both Hickory advisories before this change; both disappear with the candidate SDK. No new audit exceptions are added. An unfiltered audit still reports two pre-existing quick-xml advisories, which are unrelated to the resolver change. - Four SQS tests pass, including streamed acknowledgement bursts that reuse connections and create no blocking DNS threads. - A new loopback UDP DNS test checks IPv4 and IPv6 answers, NXDOMAIN, 64 cached lookups without new DNS traffic, and repeated queries for already-expired zero-TTL answers. It also verifies no additional runtime threads are started. It does not rely on /etc/hosts or external DNS. The first advisory concerns DNSSEC validation, which this transport does not enable. Upgrading also removes the vulnerable version from consumer dependency graphs instead of asking consumers to ignore it. This is targeted transport validation, not a repeat of a production-scale SQS benchmark. Advisories: https://rustsec.org/advisories/RUSTSEC-2026-0118.html and https://rustsec.org/advisories/RUSTSEC-2026-0119.html. Refs ALIEN-1524.
Concurrent SQS acknowledgements repeatedly open new connections because the shared HTTP client retains only four idle connections and successful responses are dropped before their bodies finish. DNS lookups for those connections run in Tokio's blocking pool.
Drain successful response bodies so HTTP connections can return to the pool. Give the SQS transport a bounded pool of 512 idle connections per host with a 30-second idle timeout, and a per-client async DNS resolver with TTL caching. The DNS change is scoped to SQS. The shared response-body fix also applies to other clients using
send_no_response.Validation:
Seven targeted tests pass, including signed SQS acknowledgement bursts with streamed metadata, truncated-body errors, and a retrying mutation that makes exactly one request after successful headers.
Counterfactual checks fail with the old idle pool limit, the blocking DNS resolver, or discarded response bodies.
Built the release native addon and embedded it in a standalone Bun 1.4.2 executable with seven JavaScript workers and two queue receivers. With the source and addon files absent from disk, approximately 29,000 acknowledgement requests with fragmented responses used 512 connections and seven Tokio threads, with no DNS worker stacks.
Validated the exact PR head as an embedded native addon in a compiled Bun 1.4.2 Linux ARM64 application on real AWS: seven Workers, a seven-core CPU quota, two SQS receivers with four receive(10) loops each, 400 in-flight messages per receiver, individual acknowledgements, cached HTTP checks, Worker RPC, and SQLite updates. All data and infrastructure were synthetic and isolated.
The native baseline collapsed to 5,648 achieved HTTP RPS with 874,687 transport failures in 180 seconds, 98 Tokio threads, and 2.70 mean CPU cores. The fixed native build sustained 15,000 HTTP RPS over 360 seconds, approximately 1,500 push attempts/sec, seven Tokio threads, and 5.51 mean CPU cores. Independent SQS metrics show approximately 1,517 deletions/sec during five complete minutes.
Every timeout and overload in that fixed run occurred in its first 30 seconds. The remaining 330 seconds had 4,950,047 requests, zero timeouts or overloads, and 13 connection errors. The same-binary SDK control also had startup timeouts and overloads; its following 150 seconds had 2,250,024 successful requests. The SDK processed approximately 630 queue deletions/sec, so its queue throughput is not equivalent to native throughput.
Repeated the fixed build for ten minutes with default runtime settings: 9,000,090 requests at 15,000 RPS, 901,689 push attempts, seven Tokio threads throughout, 5.54 mean CPU cores, no restart, no CPU throttling, and no receive/ack warnings. AWS independently measured 1,503 deletions/sec over eight complete minutes. All 11,394 timeouts and 43 overloads occurred in the first 30 seconds; the following 570 seconds handled 8,550,085 requests with zero timeouts or overloads and one connection reset. The maximum per-window p99 upper bound after startup was 201 ms. Per-window request totals match the complete report.
This validates the sustained transport regression, not a zero-error cold-start guarantee or an exact reproduction of an unavailable original dataset/load command. No runtime GC/JIT override or receiver rewrite is included. Those diagnostic alternatives did not establish a repeatable complete improvement.
Body-read failures after successful headers surface as non-retryable
HTTP_RESPONSE_BODY_READ_FAILED, preserving the received HTTP status and preventing replay of accepted mutations. The async resolver reads system DNS configuration and hosts entries; OS-specific NSS plugins are not used.