Stream startup busy-waits before subscriptions are registered
- 主要语言
- Python
- 星标
- 1.5k
- 派生
- 397
- 平均合并
- 1 天 16 小时
- 30 天内合并 PR
- 6
描述
## Problem
Starting a data stream with `run()` / `_run_forever()` before registering any subscriptions causes the startup path to poll continuously. `DataStream` currently loops with `await asyncio.sleep(0)`, which yields to the event loop but remains immediately runnable and can consume an entire CPU core. `TradingStream` has the same lifecycle pattern with a 100 ms polling interval.
Subscription handlers may be registered after the stream starts, including from another thread, so the stream needs to remain idle while still reacting promptly to registration and shutdown.
## Expected behavior
- Stream startup blocks without polling until a usable subscription exists.
- Registering a subscription wakes the stream immediately.
- A shutdown request wakes the same wait path and exits without opening a websocket.
- Notifications originating outside the stream thread are delivered safely to the asyncio event loop.
## Proposed fix
Use an `asyncio.Event` owned by the stream loop. Subscription registration and shutdown should signal it with `loop.call_soon_threadsafe(event.set)`. Keep the existing thread-safe stop queue for shutdown state and check shutdown before subscription readiness when the waiter wakes.
Add regression tests confirming that idle startup performs no polling sleeps, shutdown wakes an unsubscribed stream, and subscriptions registered from another thread start the websocket promptly.
## Impact
Applications can start their stream lifecycle before registering handlers without excessive idle CPU usage or polling-induced subscription latency.
贡献指南
评估
这个 Issue 还没有评估数据。