Skip to content

feat(api): add async output collector and thread-to-loop pump bridge - #89

Merged
nosyndicate merged 3 commits into
mainfrom
phase4_41
Aug 8, 2026
Merged

feat(api): add async output collector and thread-to-loop pump bridge#89
nosyndicate merged 3 commits into
mainfrom
phase4_41

Conversation

@nosyndicate

@nosyndicate nosyndicate commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Introduces the consumer-side mailbox (OutputCollector/CollectorRegistry) and the OutputPump background thread that bridges engine-thread events onto the asyncio event loop via call_soon_threadsafe. This lays the groundwork for moving request handling off FastAPI's worker-thread pool so a waiting request becomes a suspended coroutine instead of a parked OS thread.

  • Add server/api/collector.py: OutputCollector (per-request event buffer + asyncio.Event, coalesces bursts into a single wake-up) and CollectorRegistry (request_id → collector routing, plus fail_all for shutdown)
  • Add server/api/pump.py: OutputPump, a single background thread that drains the engine's shared event queue and schedules dispatch onto the event loop via call_soon_threadsafe, including a shutdown drain to guarantee delivery of final events
  • Add unit tests for both modules in tests/api/
  • Update pyproject.toml: pin transformers<5, add protobuf dependency, add pytest-asyncio dev dependency with asyncio_mode = "auto", and configure package discovery for server/kernels

Introduces the consumer-side mailbox (OutputCollector/CollectorRegistry)
and the pump thread that bridges engine-thread events onto the asyncio
event loop via call_soon_threadsafe, laying groundwork for moving request
handling off FastAPI's worker-thread pool.
@nosyndicate
nosyndicate marked this pull request as ready for review August 2, 2026 09:59
Copilot AI review requested due to automatic review settings August 2, 2026 09:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new asyncio-friendly primitives to collect per-request output events and a background thread “pump” to bridge engine-thread events onto the asyncio event loop via call_soon_threadsafe, plus accompanying unit tests and packaging/test configuration updates.

Changes:

  • Introduce OutputCollector/CollectorRegistry for per-request buffering + async wake-ups.
  • Add OutputPump background thread to drain a shared Queue[Event] and dispatch onto the loop thread.
  • Add unit tests under tests/api/ and update pyproject.toml dependencies + pytest async configuration + package discovery.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
server/api/collector.py Adds per-request output mailbox (OutputCollector) and routing registry (CollectorRegistry).
server/api/pump.py Adds background thread pump to bridge engine-thread queue events to asyncio loop dispatch.
tests/api/test_collector.py Adds unit tests validating collector buffering, ordering, timeouts, and shutdown failure fan-out.
tests/api/test_pump.py Adds unit tests validating pump dispatch across thread/loop boundary and shutdown edge cases.
pyproject.toml Pins transformers<5, adds protobuf + pytest-asyncio, enables pytest asyncio_mode=auto, and configures package discovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/api/pump.py
Comment thread server/api/pump.py
Comment on lines +60 to +64
if self._thread is not None:
raise RuntimeError("OutputPump.start() called twice")

self._loop = loop
self._thread = threading.Thread(
Comment thread server/api/collector.py
Comment on lines +107 to +109
collector = OutputCollector()
self._collectors[request_id] = collector
return collector
@nosyndicate
nosyndicate merged commit 4ef3cef into main Aug 8, 2026
1 check passed
@nosyndicate
nosyndicate deleted the phase4_41 branch August 8, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants