🐙 userver provides a gRPC driver as userver-grpc
library. It uses namespace ugrpc::client
and namespace ugrpc::server
.
The driver wraps grpcpp
in the userver asynchronous interface.
See also:
Generate and link a library from .proto
schemas and link to it in your CMakeLists.txt
:
add_grpc_library
will link userver-grpc
transitively and will generate the usual .pb.h + .pb.cc
files. For service definitions, it will additionally generate asynchronous interfaces foo_client.usrv.pb.hpp
and foo_service.usrv.pb.hpp
.
To create gRPC clients in your microservice, register the provided ugrpc::client::ClientFactoryComponent and add the corresponding component section to the static config.
To create gRPC services in your microservice, register the provided ugrpc::server::ServerComponent and add the corresponding component section to the static config.
In a component constructor, find ugrpc::client::ClientFactoryComponent and store a reference to its ugrpc::client::ClientFactory. Using it, you can create gRPC clients of code-generated YourServiceClient
types.
Client creation in an expensive operation! Either create them once at the server boot time or cache them.
Typical steps include:
std::unique_ptr<grpc::ClientContext>
with request settingsset_deadline
for each RPCFinish
or Read
until it returns false
(otherwise the connection will close abruptly)Read the documentation on gRPC streams:
On errors, exceptions from userver/ugrpc/client/exceptions.hpp are thrown. It is recommended to catch them outside the entire stream interaction. You can catch exceptions for specific gRPC error codes or all at once.
A service implementation is a class derived from a code-generated YourServiceBase
interface class. Each service method from the schema corresponds to a method of the interface class. If you don't override some of the methods, UNIMPLEMENTED
error code will be reported for those.
To register your service:
Each method receives:
When using a server stream, always call Finish
or FinishWithError
. Otherwise the client will receive UNKNOWN
error, which signifies an internal server error.
Read the documentation on gRPC streams:
On connection errors, exceptions from userver/ugrpc/server/exceptions.hpp are thrown. It is recommended not to catch them, leading to RPC interruption. You can catch exceptions for specific gRPC error codes or all at once.
grpc.client.by-destination.FULL_SERVICE_NAME/METHOD_NAME
grpc.server.by-destination.FULL_SERVICE_NAME/METHOD_NAME
These are the metrics provided for each gRPC method:
Metric name | Description |
---|---|
timings.1min | time from RPC start to finish (utils::statistics::Percentile ) |
status.STATUS_CODE_NAME | RPCs that finished with specified status codes |
network-error | RPCs that did not finish with a status due to a network error |
abandoned-error | RPCs that we forgot to Finish (always a bug in ugrpc usage) |
rps | Requests per second: sum(status) + network-error |
eps | Errors per second: rps - status.OK |
active | The number of currently active RPCs (created and not finished) |