Skip to content

Stream startup busy-waits before subscriptions are registered #762

Description

@bitflipd

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions