Skip to content

feat: replace thread-per-consumer pub/sub with async receive pool - #1065

Merged
cybermaggedon merged 1 commit into
release/v2.8from
feature/async-receive
Jul 25, 2026
Merged

feat: replace thread-per-consumer pub/sub with async receive pool#1065
cybermaggedon merged 1 commit into
release/v2.8from
feature/async-receive

Conversation

@cybermaggedon

Copy link
Copy Markdown
Contributor

Eliminate the thread-per-consumer model that causes thread exhaustion at scale (40+ workspaces × 4 flows ≈ 480 OS threads) by migrating to pulsar.asyncio.Client with fully async receive loops.

Core infrastructure:

  • Add AsyncPulsarBackend using pulsar.asyncio.Client for native async
  • Add ReceiverPool: shared work queue with configurable worker count
  • Add SenderPool: async producer dispatch with drain-on-stop
  • Add RequestResponseClient with streaming support (request_stream)
  • Add AsyncConfigClient and AsyncRequestResponseWrapper for service use

Migration:

  • Migrate all core services to AsyncProcessor (config, flow, IAM, librarian, cores, bootstrapper, metering)
  • Replace Subscriber/Consumer inheritance with ReceiverPool registrations
  • Replace Producer send with SenderPool handles
  • Use BaseException throughout for pulsar.asyncio.PulsarException compatibility (inherits BaseException, not Exception)
  • Close-before-cancel shutdown pattern for async Pulsar consumers

Includes tech spec: docs/tech-specs/async-receive-threading.md

Eliminate the thread-per-consumer model that causes thread exhaustion
at scale (40+ workspaces × 4 flows ≈ 480 OS threads) by migrating to
pulsar.asyncio.Client with fully async receive loops.

Core infrastructure:
- Add AsyncPulsarBackend using pulsar.asyncio.Client for native async
- Add ReceiverPool: shared work queue with configurable worker count
- Add SenderPool: async producer dispatch with drain-on-stop
- Add RequestResponseClient with streaming support (request_stream)
- Add AsyncConfigClient and AsyncRequestResponseWrapper for service use

Migration:
- Migrate all core services to AsyncProcessor (config, flow, IAM,
  librarian, cores, bootstrapper, metering)
- Replace Subscriber/Consumer inheritance with ReceiverPool registrations
- Replace Producer send with SenderPool handles
- Use BaseException throughout for pulsar.asyncio.PulsarException
  compatibility (inherits BaseException, not Exception)
- Close-before-cancel shutdown pattern for async Pulsar consumers

Includes tech spec: docs/tech-specs/async-receive-threading.md
@github-actions

Copy link
Copy Markdown

Contributor License Agreement ✅

All contributors have signed the CLA. Thank you!

@cybermaggedon
cybermaggedon merged commit 80c6cad into release/v2.8 Jul 25, 2026
2 of 3 checks passed
@cybermaggedon
cybermaggedon deleted the feature/async-receive branch July 25, 2026 09:00
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.

1 participant