Repository navigation
perf(http): pool remaining raw aiohttp.ClientSession sites onto shared client (#12979) - #13006
Merged
Merged
Conversation
…d client (#12979) Converts the last 10 convertible per-request ClientSession sites (mock_providers, media/link pipeline, onboarding doctor, command extraction, notifications, whatsapp media download, description compressor, cloud ASR providers, tilde provider, OpenAI realtime SDP proxy) to autobot_shared.http_client.tracked_request(), and documents 2 newly-found long-lived carve-outs in services/npu_pipeline/ so the remaining 12 raw sites are all intentional, in-code-documented exceptions.
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
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.
Thinking Path
Batch 9 of #12979 — read the issue's comment history for the consolidated recipe and per-batch gotchas (test-seam retargeting,
raise_for_status()not implyingget_json(),connector=pre-screen). Measured the true remaining set with the ceiling test's ownraw_client_session_sites()AST walker (22 sites), pre-screened all candidate files forconnector=(none found — no hidden SSRF pins in this batch), then read every site individually per the recipe's standing rule before classifying ittracked_request()vs RAW carve-out.Two of the task's 12 candidate files turned out, on inspection, to be long-lived/returned-session carve-outs rather than convertible sites —
services/npu_pipeline/dispatcher.py(instance-owned session reused across every worker in a pipeline pass, including the token-streaming leg) andservices/npu_pipeline/npu_client.py(accepts an externally-owned session and fires concurrentasyncio.gather()calls over the same instance session) — both the same shape asservices/npu_client.py's_get_session()carve-out from batch 7. Left RAW with in-code comments instead of converting.voice_processing/realtime/openai_provider.pywas flagged in the task as "very likely a WebSocket session" — on inspection it is a plain multipart HTTP POST (WebRTC negotiation happens client-side in the browser; the Python code only proxies the SDP offer/answer), so it converts normally.What Changed
Converted to
tracked_request()(10 files, 10 sites — 0%get_json()/post_json(), continuing every prior batch's finding that the ratio tracks the module's contract, not the codebase):tracked_request()llm_shared/mock_providers.pyLocalLLM.generate().text()on failure branch before returning a sentinelmedia/link/pipeline.py_fetch_and_parse().text()/.headers/.status, branches on>=400onboarding/doctor.py_probe_http().status < 500, never raises (health probe — addedsuppress_error_log=True)services/command_extraction_service.py_slm_exec().json()unconditionally, noraise_for_status(),ssl=Falseforwards as a per-request kwargservices/notification_service.py_send_webhook().text()on>=400beforeraise_for_status()services/whatsapp_service.pydownload_whatsapp_media().status, reads.read()tools/description_compressor.py_compress_via_ollama()None,json(content_type=None)voice_processing/providers/cloud/base.py+deepgram_provider.py+assemblyai_provider.py_make_session()factory (removed) + 4 call sites (_call_api,_upload,_submit,_poll)tracked_request()with the shared_DEFAULT_TIMEOUT(600s) passed per-requestvoice_processing/providers/lv/tilde_provider.py_call_tilde_api().text()on failure, multipartFormDataforwards fine asdata=voice_processing/realtime/openai_provider.py_post().read()bytes, custom status mappingNew RAW carve-outs documented (2 files, long-lived, found by reading — not in the task's scope list):
services/npu_pipeline/dispatcher.py—PipelineDispatcher.__aenter__(): session held for the instance's full lifetime, reused across every worker in the pipeline plan including token streaming.services/npu_pipeline/npu_client.py—NPUClient.__aenter__(): accepts an externally-owned session and fires concurrentpartial_forward()calls viaasyncio.gather()over the same instance session.Ceiling guard (
tests/test_raw_client_session_ceiling_12992.py):MAX_RAW_CLIENT_SESSIONS22 → 12, re-measured with the file's own AST walker against a tree freshly synced toorigin/Dev_new_guiimmediately before push (confirmed not behind). Added a "Remaining raw sites" list to the module docstring enumerating all 12 remaining sites and their carve-out category (5 SSRF-pinned-connector files, 4 long-lived files, 2 custom-TLS files), so the next reader sees "intentional" rather than "unfinished".Test-seam retargeting (6 test files, all the "mock
aiohttp.ClientSessiondirectly" variant found via the repo-widepatch(.*ClientSessiongrep):media/link/pipeline_test.py(7 sites),services/command_extraction_service_test.py(2),tests/services/notification_service_test.py(2),voice_processing/providers/cloud/test_cloud_providers.py(3 — 2 deepgram + 1 assemblyaipatch.object(_make_session)),voice_processing/realtime/registry_test.py(2),api/realtime_session_test.py(12 — the widest blast radius this batch, a router-level test file sharing no name with the convertedopenai_provider.py). All retargeted topatch.object(get_http_client(), "tracked_request", ...).Pre-existing bugs found (filed, not fixed — different scope):
services/npu_pipeline/test_dispatcher.py'smock_posthelpers are declaredasync defbut called synchronously bydispatcher.py, breaking all 5 of that file's tests; confirmed pre-existing viacp-swap againstorigin/Dev_new_gui.voice_processing/providers/test_registry.py::test_get_speech_provider_conveniencedepends on import-order side effects from another test module and fails when run standalone; confirmed pre-existing viacp-swap.Verification
(a) Static checks, all 21 touched files:
(b) Leak/counter exercise: each converted call path exercised locally against real
tracked_request()semantics via the retargeted unit tests (success + failure branches per site).(c) Baseline-vs-after diff (never trusted a passing suite alone): curated regression scope run before AND after conversion —
Repo-wide
grep -rln 'patch(.*ClientSession're-run after all edits: only 5 files remain, all for carve-outs this batch didn't touch (test_dispatcher.py,test_external_importer_ssrf.py,ssrf_guard_test.py,knowledge_api_integration_test.py,helpers_reorganization_test.py) — confirmed unrelated to any converted module.(d) Ceiling, measured not computed:
raw_client_session_sites()AST walker on a tree freshly synced toorigin/Dev_new_guiimmediately before push (confirmed not behind): 22 → 12 (exactly the 10 files converted). Negative-case check: monkeypatchingMAX_RAW_CLIENT_SESSIONSto 11 trips the assertion as expected.Recommendation on exact-vs-ceiling: at 12, every remaining raw site is a documented, deliberate carve-out (SSRF-pinned connector / long-lived session / custom TLS) — none are backlog. I'd lean toward converting the assertion to
== 12now that the "moving base while batches are in flight" problem this ceiling was built to survive no longer applies (there's no more batch work in flight to race against). That said, an exact-equality assertion means any new rawClientSession(...)anywhere in the tree — even a legitimate new carve-out — trips CI until the test file itself is updated, which is arguably the point of a gate. I'm flagging this rather than changing the assertion semantics unilaterally, per the task's instruction.Model Used
Sonnet (claude-sonnet-5)