Skip to content

async: add stdexec coroutine primitives + gRPC coroutine reply path#323

Merged
szmyd merged 2 commits into
eBay:dev/v14.xfrom
szmyd:dev/v14.x
Jun 2, 2026
Merged

async: add stdexec coroutine primitives + gRPC coroutine reply path#323
szmyd merged 2 commits into
eBay:dev/v14.xfrom
szmyd:dev/v14.x

Conversation

@szmyd

@szmyd szmyd commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator
  • async/value_awaitable.hpp: cross-thread single-shot awaitable carrying T (generalizes cqe_awaitable from int->T). Producer complete(T) from any thread, consumer co_awaits; same lock-free init/waiting/done acq_rel handshake that restores folly::Future's cross-thread happens-before.
  • async/task.hpp: using task = exec::task<T> currency alias (opt-in header; needs stdexec).
  • async/when_all.hpp: dynamic (runtime-vector) fan-out when_all(vector<task>) -> task<vector>. Counting latch on value_awaitable; errors-as-values, never short-circuits (broadcast semantics ignore per-peer errors). T must be default-constructible.
  • grpc/rpc_client: GenericRpcDataCoroBlob + GenericAsyncStub::call_unary_co deliver a coroutine reply ALONGSIDE the std::future one (value_awaitable.complete fires from the gRPC CQ worker thread). Stays stdexec-free; when_all composition lives a layer up at nuraft_mesg.

szmyd and others added 2 commits June 2, 2026 01:10
Phase 0 of the stack-wide folly/std::future -> exec::task migration. All
additive (existing std::future paths untouched), so consumers can adopt
incrementally.

- async/value_awaitable.hpp: cross-thread single-shot awaitable carrying T
  (generalizes cqe_awaitable from int->T). Producer complete(T) from any
  thread, consumer co_awaits; same lock-free init/waiting/done acq_rel
  handshake that restores folly::Future's cross-thread happens-before.
- async/task.hpp: `using task = exec::task<T>` currency alias (opt-in header;
  needs stdexec).
- async/when_all.hpp: dynamic (runtime-vector) fan-out
  when_all(vector<task<T>>) -> task<vector<T>>. Counting latch on
  value_awaitable; errors-as-values, never short-circuits (broadcast
  semantics ignore per-peer errors). T must be default-constructible.
- grpc/rpc_client: GenericRpcDataCoroBlob + GenericAsyncStub::call_unary_co
  deliver a coroutine reply ALONGSIDE the std::future one
  (value_awaitable.complete fires from the gRPC CQ worker thread). Stays
  stdexec-free; when_all composition lives a layer up at nuraft_mesg.

Test: test_value_awaitable (8/8, incl 2000-iter cross-thread handshake,
registered unconditionally -- no stdexec needed).
@szmyd szmyd merged commit c99ca66 into eBay:dev/v14.x Jun 2, 2026
5 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