perf(status): parallelize independent adapter reads (closes #31) - #32
Merged
Conversation
Follow-up to #28. After the cheap ref list + client cache, /api/state on a remote store was still ~5s: the independent per-collection list_record_ids distincts, the batch get_records/get_heads, and list_history_refs each cost one RTT and ran serially, so they summed on a cross-region link. Add _gather() (a bounded ThreadPoolExecutor map) and route _all_refs and _batch_live_and_heads through it. pymongo/psycopg release the GIL during network I/O, so the round-trips overlap instead of summing — ~sum becomes ~max(single op). Safe for both adapters: MongoClient is thread-safe/pooled, and the Postgres connection cache is already thread-local so each worker gets its own connection. Verified: status() output is byte-identical to serial (50 rows, drift intact); with a simulated 300ms/call RTT, status() drops from ~8.4s serial to ~1.5s.
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.
Follow-up to #28. After the cheap ref list + shared MongoClient,
/api/stateon a remote store was still ~5s — the independent reads ran serially, so each RTT summed on a cross-region link (as profiled in #31).Fix
Add
_gather()(a boundedThreadPoolExecutormap) and route the two hot spots through it:_all_refs— per-collectionlist_record_idsdistincts +list_history_refsnow run concurrently._batch_live_and_heads— the per-collectionget_records+get_headsnow run concurrently.pymongo/psycopg release the GIL during network I/O, so the round-trips overlap instead of summing (~sum → ~max(single op)). Safe for both adapters:
MongoClientis thread-safe/pooled, and the Postgres connection cache is already thread-local (each worker thread gets its own connection).Verification
status()output is byte-identical to serial (50 rows, drift intact);_all_refsstable.status()drops from ~8.4s serial → ~1.5s (~5.5×), matching perf(ui): /api/state still ~5s on remote store — serialize-to-parallel the remaining per-collection round-trips (follow-up to #28) #31's5s→1s estimate.Net: on a remote store this should take the warm UI from ~5s to ~1–1.5s (and helps cold too). Local stores were already instant.
Also answers the '19s first time' question: cold load = one-time MongoClient TLS/SRV handshake (~2s, cached after) + cold Atlas caches on top of the serial round-trips; parallelizing collapses the round-trip portion whether warm or cold.