Skip to content

Add asynchronous RPC support to co::Coroutine rpc server#86

Merged
dallison merged 1 commit into
mainfrom
async-rpc
Jun 10, 2026
Merged

Add asynchronous RPC support to co::Coroutine rpc server#86
dallison merged 1 commit into
mainfrom
async-rpc

Conversation

@dallison

Copy link
Copy Markdown
Owner

Summary

  • Reworks the co::Coroutine-based rpc server so non-streaming methods run as a two-coroutine pipeline: a request coroutine dispatches incoming requests to the handler, and a response coroutine drains completed replies from a toolbelt::SharedPtrPipe and publishes them to the client.
  • Handlers now receive reply/error callbacks and may complete their reply later (e.g. after yielding/sleeping on their coroutine), decoupling request dispatch from response delivery.
  • Adds the public RegisterMethodAsync(...) API. Existing synchronous RegisterMethod overloads are now thin wrappers over it, preserving prior behavior (including the "Error executing method <name>: ..." error formatting).
  • Reply writes pass the request coroutine to SharedPtrPipe::Write, so a momentarily full reply pipe yields the coroutine (letting the response coroutine drain it) instead of blocking the scheduler thread or silently dropping the reply.

Design notes

  • The whole server runs on a single coroutine scheduler thread, so no locking is used; replies are produced on the request coroutine that owns them.
  • The response coroutine dups the interrupt fd so it can wait on both the reply pipe and shutdown without violating the epoll "one waiter per fd" restriction.

Test plan

  • bazelisk test //rpc/... — all pass (client_test, server_test, rpc_test)
  • New ServerTest.CallAsyncMethod exercises the async reply path (handler defers its reply via coroutine work before completing)

Non-streaming methods now run as a two-coroutine pipeline: a request
coroutine dispatches incoming requests to the handler, and a response
coroutine drains completed replies from a toolbelt::SharedPtrPipe and
publishes them to the client. Handlers receive reply/error callbacks and
may complete their reply later (e.g. after yielding on their coroutine),
decoupling request dispatch from response delivery.

Existing synchronous RegisterMethod overloads are now thin wrappers over
the new RegisterMethodAsync, preserving behavior including error message
formatting. Reply writes pass the request coroutine so a momentarily full
reply pipe yields instead of blocking the scheduler thread. Adds an
async-path test (CallAsyncMethod) that defers its reply via coroutine work.
@dallison dallison merged commit 6860cbb into main Jun 10, 2026
34 checks passed
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