asio-grpc v1.5.0
Asynchronous gRPC with Asio/unified executors
Completion token

The last argument to all async functions in this library is a CompletionToken. It can be used to customize how to receive notification of the completion of the asynchronous operation. Some examples:

Callback

agrpc::wait(alarm, deadline, asio::bind_executor(grpc_context, [&](bool /*wait_ok*/) {}));
constexpr detail::WaitFn wait
Wait for a timer.
Definition: wait.hpp:72

Stackless coroutine

struct Coro : asio::coroutine
{
using executor_type = agrpc::GrpcContext::executor_type;
struct Context
{
std::chrono::system_clock::time_point deadline;
agrpc::GrpcContext& grpc_context;
grpc::Alarm alarm;
Context(std::chrono::system_clock::time_point deadline, agrpc::GrpcContext& grpc_context)
: deadline(deadline), grpc_context(grpc_context)
{
}
};
std::shared_ptr<Context> context;
Coro(std::chrono::system_clock::time_point deadline, agrpc::GrpcContext& grpc_context)
: context(std::make_shared<Context>(deadline, grpc_context))
{
}
void operator()(bool wait_ok)
{
BOOST_ASIO_CORO_REENTER(*this)
{
BOOST_ASIO_CORO_YIELD agrpc::wait(context->alarm, context->deadline, std::move(*this));
(void)wait_ok;
}
}
executor_type get_executor() const noexcept { return context->grpc_context.get_executor(); }
};
Coro{deadline, grpc_context}(false);
Execution context based on grpc::CompletionQueue
Definition: grpcContext.hpp:50
agrpc::BasicGrpcExecutor<> executor_type
The associated executor type.
Definition: grpcContext.hpp:55

use_sender

In libunifex senders are awaitable. agrpc::use_sender causes RPC step functions to return a sender. They can be combined with unifex::task to asynchronously process RPCs using co_await:

unifex::task<void> unified_executors(example::v1::Example::Stub& stub, agrpc::GrpcContext& grpc_context)
{
grpc::ClientContext client_context;
example::v1::Request request;
std::unique_ptr<grpc::ClientAsyncReader<example::v1::Response>> reader;
co_await agrpc::request(&example::v1::Example::Stub::AsyncServerStreaming, stub, client_context, request, reader,
agrpc::use_sender(grpc_context));
example::v1::Response response;
co_await agrpc::read(*reader, response, agrpc::use_sender(grpc_context));
grpc::Status status;
co_await agrpc::finish(*reader, status, agrpc::use_sender(grpc_context));
}
constexpr detail::UseSenderFn use_sender
Create sender completion token.
Definition: useSender.hpp:66
constexpr detail::RequestFn request
Start a new RPC.
Definition: rpc.hpp:1394
constexpr detail::ReadFn read
Read from a streaming RPC.
Definition: rpc.hpp:1403
constexpr detail::FinishFn finish
Finish a RPC.
Definition: rpc.hpp:1430

Custom allocator

Asio-grpc will attempt to get the associated allocator of the completion handler by calling asio::get_associated_allocator. If there is none then it will retrieve it from the executor through the allocator property.

The associated allocator can be customized using agrpc::bind_allocator (or asio::bind_allocator since Boost.Asio 1.79):

co_await agrpc::wait(alarm, deadline, agrpc::bind_allocator(my_allocator, asio::use_awaitable));
auto bind_allocator(const Allocator &allocator, Target &&target)
Helper function to create an agrpc::AllocatorBinder.
Definition: bindAllocator.hpp:205

The allocator property can be set as follows:

alarm, deadline,
asio::bind_executor(asio::require(grpc_context.get_executor(), asio::execution::allocator(my_allocator)),
[&](bool /*wait_ok*/) {}));
executor_type get_executor() noexcept
Get the associated executor.
Definition: grpcContext.ipp:88