Add opt-in persistent connection pooling to PostsData#166
Draft
maximus1108 wants to merge 1 commit intomainfrom
Draft
Add opt-in persistent connection pooling to PostsData#166maximus1108 wants to merge 1 commit intomainfrom
maximus1108 wants to merge 1 commit intomainfrom
Conversation
When a class that includes PostsData sets `self.persistent_connections = true`, `raw_ssl_request` will use a per-class Net::HTTP::Persistent pool instead of creating a fresh Net::HTTP instance per request. This enables TCP+TLS connection reuse across requests to the same host, eliminating repeated handshake overhead. Key design decisions: - Opt-in via class attribute (default: false) — zero behavior change for existing consumers - Per-class pool isolation — each including class gets its own pool instance - Per-request timeout override — pool.read_timeout is set before each request, supporting dynamic timeouts (e.g., carrier services with 3-10s based on throughput) - Error compatibility — network errors are caught and re-raised as ActiveUtils::ConnectionError, preserving existing rescue clauses - Return type unchanged — raw_ssl_request still returns Net::HTTP::HTTPResponse Pool configuration attributes: - pool_size (default: 100) — global cap on total connections across all hosts/threads - pool_idle_timeout (default: 60s) — idle connections closed on next checkout - pool_keep_alive (default: 60s) — HTTP Keep-Alive header timeout - pool_max_requests (default: 100) — recycle connection after N requests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
persistent_connectionsclass attribute toPostsDatamoduleraw_ssl_requestuses a per-classNet::HTTP::Persistentpool instead of creating a freshNet::HTTPper requestMotivation
Carrier service rate requests in Shopify Core create a new TCP+TLS connection for every single HTTP request via
ActiveUtils::PostsData→Connection→Net::HTTP.new. For high-latency third-party hosts (e.g., carriers in Argentina at ~115ms RTT), the handshake alone costs ~345ms — 63% of the total request time.By pooling connections and reusing them for subsequent requests to the same host, we can eliminate this overhead entirely on warm hits, reducing p95 latency from ~600ms to ~250ms for these carriers.
See the full context document for detailed analysis of the problem, host distribution (55K hosts, power-law — top 50 handle 84% of volume), worker threading model (29 threads/pod), and pool sizing rationale.
Design
self.persistent_connections = trueafterinclude ActiveUtils::PostsDataNet::HTTP::Persistentinstancepool.read_timeoutis set before eachrequestcall, supporting dynamic timeoutsActiveUtils::ConnectionError/ResponseErrorraw_ssl_requeststill returnsNet::HTTP::HTTPResponseConfiguration
Test plan
posts_data_test.rbtests pass unchanged (verified: 8/8)connection_test.rbtests pass unchanged (verified: 32/32)network_connection_retries_test.rbtests pass unchanged (verified: 23/23)🤖 Generated with Claude Code