gabriel / muse public
feat BREAKING transport task/wire-h2-strict #1 / 1
AI Agent gabriel · 152 days ago · Apr 22, 2026 · Diff

feat(transport): HTTP/2 streaming everywhere via shared httpx client

- Add _get_wire_client() singleton: one httpx.Client(http2=True) per process, shared across all MuseWire calls — one TLS handshake, all requests multiplex - push_stream: HTTPS routes through httpx exclusively; HTTPX_AVAILABLE=False raises TransportError (no HTTP/1.1 fallback for HTTPS) - fetch_stream: HTTPS streams via httpx client.stream(); HTTP stays on http.client - _execute (negotiate, fetch_remote_info, presign_objects): HTTPS via client.request() instead of urllib; HTTP path unchanged - Plain HTTP URLs (localhost) keep http.client chunked path — no h2c needed - Tests: 19 new tests in test_wire_h2_strict.py covering T16–T23 - Tests: test_transport_http2.py and test_core_transport.py updated to patch _get_wire_client instead of _httpx_mod/_open_url - Docs: musewire-performance.md defines GitHub-level performance checklist and inviolable rules (no fallbacks, shared client, server must stream)

sha256:1186192b3327dac73c16a6b71476be4b2b31ff351d9da7191efae84773d1cecd sha
+86 ~30 −5 symbols
sha256:9c61411ecbdc0bc7aef9bf04f3d0adf2a4d8533d1397da5ecf6e1440d9278bed snapshot
+86
symbols added
~30
symbols modified
−5
symbols removed
0
dead code introduced
Semantic Changes 121 symbols
~ docs/protocol/musewire-performance.md .md 26 symbols added
+ MuseWire Protocol — GitHub-Level Performance Checklist section MuseWire Protocol — GitHub-Level Performance Checklist L1–324
+ py) section Checklist — Client side (muse/core/transport.py) L66–175
+ Connection / TLS section Connection / TLS L149–163
+ HTTP library section HTTP library L68–96
+ Large-object presigned upload path section Large-object presigned upload path L163–175
+ fetch_remote_info (refs) section fetch_remote_info (refs) L135–139
+ fetch_stream section fetch_stream L114–129
+ negotiate section negotiate L129–135
+ presign_objects section presign_objects L139–143
+ push_stream / _push_stream_httpx section push_stream / _push_stream_httpx L96–114
+ push_tags, create_release, list_releases_remote, delete_* section push_tags, create_release, list_releases_remote, delete_* L143–149
+ Checklist — Commands that touch MuseWire section Checklist — Commands that touch MuseWire L247–266
+ table@L249 section table@L249 L249–259
+ py) section Checklist — Server side (musehub/musehub/api/routes/wire.py) L175–247
+ Cloudflare configuration section Cloudflare configuration L228–247
+ fetch_stream endpoint (line 463) section fetch_stream endpoint (line 463) L212–223
+ presign_objects endpoint (line 277) section presign_objects endpoint (line 277) L223–228
+ push_stream endpoint (line 212) section push_stream endpoint (line 212) L177–212
+ Current architecture diagram section Current architecture diagram L42–66
+ code@L44 variable variable code@L44 L44–63
+ Done criteria section Done criteria L312–324
+ Implementation order section Implementation order L281–312
+ Inviolable rules section Inviolable rules L23–42
+ What GitHub actually does (the reference model) section What GitHub actually does (the reference model) L266–281
+ table@L268 section table@L268 L268–278
+ Why we keep churning on this section Why we keep churning on this L9–23
~ tests/test_wire_h2_strict.py .py 52 symbols added
+ TestT16PushStreamNoFallback class class TestT16PushStreamNoFallback L104–192
+ test_https_push_never_uses_http_client method method test_https_push_never_uses_http_client L166–192
+ test_httpx_error_does_not_call_open_chunked_connection method method test_httpx_error_does_not_call_open_chunked_connection L134–164
+ test_httpx_error_propagates_as_transport_error method method test_httpx_error_propagates_as_transport_error L107–132
+ TestT17FetchStreamHttpx class class TestT17FetchStreamHttpx L199–247
+ _make_client_and_frames method method _make_client_and_frames L202–212
+ test_fetch_stream_does_not_use_urllib method method test_fetch_stream_does_not_use_urllib L237–247
+ test_fetch_stream_uses_http2_true method method test_fetch_stream_uses_http2_true L225–235
+ test_fetch_stream_uses_httpx_client method method test_fetch_stream_uses_httpx_client L214–223
+ TestT18NegotiateHttpx class class TestT18NegotiateHttpx L254–283
+ _make_client method method _make_client L257–260
+ test_negotiate_does_not_use_urllib method method test_negotiate_does_not_use_urllib L273–283
+ test_negotiate_uses_httpx_client method method test_negotiate_uses_httpx_client L262–271
+ TestT19FetchRemoteInfoHttpx class class TestT19FetchRemoteInfoHttpx L290–323
+ _make_client method method _make_client L293–300
+ test_fetch_remote_info_does_not_use_urllib method method test_fetch_remote_info_does_not_use_urllib L313–323
+ test_fetch_remote_info_uses_httpx method method test_fetch_remote_info_uses_httpx L302–311
+ TestT20PresignHttpx class class TestT20PresignHttpx L330–361
+ _make_client method method _make_client L333–336
+ test_presign_does_not_use_urllib method method test_presign_does_not_use_urllib L350–361
+ test_presign_uses_httpx method method test_presign_uses_httpx L338–348
+ TestT21SharedClient class class TestT21SharedClient L368–412
+ test_get_wire_client_exists method method test_get_wire_client_exists L371–375
+ test_get_wire_client_no_redirects method method test_get_wire_client_no_redirects L406–412
+ test_get_wire_client_returns_httpx_client method method test_get_wire_client_returns_httpx_client L377–381
+ test_get_wire_client_returns_same_instance method method test_get_wire_client_returns_same_instance L383–387
+ test_get_wire_client_uses_http2 method method test_get_wire_client_uses_http2 L389–404
+ TestT22PushStreamNoRawConn class class TestT22PushStreamNoRawConn L419–446
+ test_no_open_chunked_connection_on_success method method test_no_open_chunked_connection_on_success L422–446
+ TestT23NoHttpxRaises class class TestT23NoHttpxRaises L453–477
+ test_no_httpx_push_raises_transport_error method method test_no_httpx_push_raises_transport_error L456–477
+ _end_frame function function _end_frame L45–46
+ _make_objects function function _make_objects L57–58
+ _mock_httpx_client function function _mock_httpx_client L82–91
+ _mock_httpx_mod function function _mock_httpx_mod L94–97
+ _mock_httpx_response function function _mock_httpx_response L72–79
+ _mock_httpx_streaming_response function function _mock_httpx_streaming_response L61–69
+ _object_frame function function _object_frame L49–54
+ _oid function function _oid L33–34
+ _progress_frame function function _progress_frame L41–42
+ _result_frame function function _result_frame L37–38
+ Iterator import import Iterator L19–19
+ MagicMock import import MagicMock L20–20
+ ObjectPayload import import ObjectPayload L25–25
+ PushResult import import PushResult L25–25
+ annotations import import annotations L16–16
+ blob_id import import blob_id L26–26
+ call import import call L20–20
+ msgpack import import msgpack L22–22
+ patch import import patch L20–20
+ pytest import import pytest L23–23
+ types import import types L18–18
~ muse/core/transport.py .py 3 symbols added, 12 symbols modified
+ _get_wire_client function function _get_wire_client L175–195
+ _wire_client variable variable _wire_client L172–172
+ Iterable import import Iterable L113–113
~ IO
~ tests/test_transport_http2.py .py 4 symbols added, 5 symbols removed, 4 symbols modified
mock_httpx method method mock_httpx L83–95
test_http1_fallback_when_httpx_unavailable method method test_http1_fallback_when_httpx_unavailable L146–180
test_http_url_always_uses_http1 method method test_http_url_always_uses_http1 L182–217
test_httpx_client_is_instantiated method method test_httpx_client_is_instantiated L122–124
test_httpx_client_uses_http2_true method method test_httpx_client_uses_http2_true L126–131
+ _make_mock_client method method _make_mock_client L82–88
+ test_http_url_uses_http1_chunked method method test_http_url_uses_http1_chunked L155–183
+ test_httpx_stream_called method method test_httpx_stream_called L114–117
+ test_no_httpx_raises_transport_error_for_https method method test_no_httpx_raises_transport_error_for_https L133–153
~ _push
← Older Oldest on task/wire-h2-strict
All commits
Newer → Latest on task/wire-h2-strict

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:1186192b3327dac73c16a6b71476be4b2b31ff351d9da7191efae84773d1cecd --body "your comment"