* fix(streaming): lock-disciplined STREAMS reads via peek_stream() Writers pop STREAMS under STREAMS_LOCK, but four hot reads used bare STREAMS.get(): the streaming worker start, the gateway run start, and the two SSE attach paths in routes.py. Each is individually saved today by GIL-atomic dict.get plus a None-guard, but the check-then-act windows (get → register, get → subscribe) race teardown pops, and the bare pattern invites unprotected copies. peek_stream() centralizes the locked read; all four sites migrate with no behavioral change. * test: dual-patch config.STREAMS alongside routes.STREAMS in SSE seam tests peek_stream() reads the canonical api.config.STREAMS registry; tests that inject a fake registry by patching only the routes-level re-export left the helper reading the real (empty) registry and hung the SSE loop to the pytest-timeout ceiling. Mirror the test_issue6623 pattern: patch both bindings. * docs(changelog): stamp #7339 lock-disciplined STREAMS reads --------- Co-authored-by: Sebastian B <sb@wmc.sh> Co-authored-by: n <a@n>
This commit is contained in:
8 files changed
+143
-4
No files matched your search
@@ -9209,6 +9209,21 @@ def create_stream_channel() -> StreamChannel:
|
||||
|
||||
STREAMS: dict = {}
|
||||
STREAMS_LOCK = threading.Lock()
|
||||
|
||||
|
||||
def peek_stream(stream_id):
|
||||
"""Lock-disciplined stream queue lookup.
|
||||
|
||||
Writers mutate STREAMS under STREAMS_LOCK (teardown in api/streaming.py,
|
||||
the route layer's start/cancel paths); reads must take the same lock so a
|
||||
read racing a teardown pop can never observe-and-use a queue the registry
|
||||
has already released. Returns the queue or None — callers keep their
|
||||
existing None-guard fallbacks.
|
||||
"""
|
||||
with STREAMS_LOCK:
|
||||
return STREAMS.get(stream_id)
|
||||
|
||||
|
||||
# stream_id -> session_id owner, populated synchronously before worker startup so
|
||||
# stream-id authorization does not depend on worker lifecycle registration.
|
||||
STREAM_SESSION_OWNERS: dict = {}
|
||||
|
||||
Reference in new issue
Block a user