Skip to content

Commit 0464dff

Browse files
committed
feat docs: document the gRPC retries and timeouts
Tests: протестировано CI commit_hash:e92223d5722e5c37c8f5b88278780695b9e28f6c
1 parent 8ab036b commit 0464dff

13 files changed

Lines changed: 237 additions & 36 deletions

File tree

.mapping.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4003,6 +4003,7 @@
40034003
"scripts/docs/en/userver/grpc/middlewares_toggle.md":"taxi/uservices/userver/scripts/docs/en/userver/grpc/middlewares_toggle.md",
40044004
"scripts/docs/en/userver/grpc/server_middleware_implementation.md":"taxi/uservices/userver/scripts/docs/en/userver/grpc/server_middleware_implementation.md",
40054005
"scripts/docs/en/userver/grpc/server_middlewares.md":"taxi/uservices/userver/scripts/docs/en/userver/grpc/server_middlewares.md",
4006+
"scripts/docs/en/userver/grpc/timeouts_retries.md":"taxi/uservices/userver/scripts/docs/en/userver/grpc/timeouts_retries.md",
40064007
"scripts/docs/en/userver/http_server.md":"taxi/uservices/userver/scripts/docs/en/userver/http_server.md",
40074008
"scripts/docs/en/userver/http_server_middlewares.md":"taxi/uservices/userver/scripts/docs/en/userver/http_server_middlewares.md",
40084009
"scripts/docs/en/userver/intro.md":"taxi/uservices/userver/scripts/docs/en/userver/intro.md",

grpc/functional_tests/lowlevel/static_config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ components_manager:
1515
# The TaskProcessor for blocking connection initiation
1616
blocking-task-processor: grpc-blocking-task-processor
1717

18+
# /// [retry configuration]
19+
# yaml
1820
# Creates gRPC clients
1921
grpc-client-factory:
2022
disable-all-pipeline-middlewares: true
@@ -27,6 +29,7 @@ components_manager:
2729
# https://grpc.github.io/grpc/core/group__grpc__arg__keys.html
2830
channel-args: {}
2931

32+
# Transparent retries configuration
3033
default-service-config: >
3134
{
3235
"methodConfig": [{
@@ -46,6 +49,7 @@ components_manager:
4649
}
4750
}]
4851
}
52+
# /// [retry configuration]
4953

5054
grpc-client-middlewares-pipeline: {}
5155

grpc/functional_tests/middleware_client/static_config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ components_manager:
2626
grpc-client-headers-propagator:
2727
skip-headers:
2828
skipped-header: true
29+
# /// [grpc client factory]
30+
# yaml
2931
grpc-client-factory:
3032
middlewares:
3133
grpc-client-deadline-propagation:
3234
enabled: false
3335
retry-config:
3436
attempts: 2
3537
channel-args: {}
38+
# /// [grpc client factory]
3639

3740
greeter-client:
3841
endpoint: $greeter-client-endpoint

grpc/include/userver/ugrpc/client/simple_client_component.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ class SimpleClientComponent : public impl::SimpleClientComponentAny {
7777
: SimpleClientComponentAny(config, context),
7878
client_(FindFactory(config, context).MakeClient<Client>(MakeClientSettings(config, nullptr))) {}
7979

80-
/// To use a ClientQos config,
80+
/// To use a ClientQos config, derive from SimpleClientComponent and provide the parameter at construction:
81+
/// @snippet samples/grpc_service/src/greeter_client.hpp component
8182
SimpleClientComponent(
8283
const components::ComponentConfig& config,
8384
const components::ComponentContext& context,
@@ -86,7 +87,7 @@ class SimpleClientComponent : public impl::SimpleClientComponentAny {
8687
: SimpleClientComponentAny(config, context),
8788
client_(FindFactory(config, context).MakeClient<Client>(MakeClientSettings(config, &client_qos))) {}
8889

89-
/// @@brief Get gRPC service client
90+
/// @brief Get gRPC service client
9091
Client& GetClient() { return client_; }
9192

9293
private:

grpc/src/ugrpc/client/impl/retry_policy.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ USERVER_NAMESPACE_BEGIN
44

55
namespace ugrpc::client::impl {
66

7+
/// [retryable]
78
bool IsRetryable(grpc::StatusCode status_code) noexcept {
89
switch (status_code) {
910
case grpc::StatusCode::CANCELLED:
@@ -18,6 +19,7 @@ bool IsRetryable(grpc::StatusCode status_code) noexcept {
1819
return false;
1920
}
2021
}
22+
/// [retryable]
2123

2224
} // namespace ugrpc::client::impl
2325

grpc/tests/retry_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ UTEST_F(RetryTest, CallOptionsAttempts) {
5858

5959
sample::ugrpc::GreetingRequest request;
6060
request.set_name("testname");
61-
61+
/// [SetAttempts]
6262
ugrpc::client::CallOptions call_options;
6363
call_options.SetAttempts(4);
6464

6565
sample::ugrpc::GreetingResponse response;
6666
UEXPECT_NO_THROW(response = client.SayHello(request, std::move(call_options)));
67+
/// [SetAttempts]
6768
}
6869

6970
USERVER_NAMESPACE_END

samples/grpc_service/src/greeter_client.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@
1212

1313
namespace samples {
1414

15+
const dynamic_config::Key<ugrpc::client::ClientQos> kGreeterClientQos{
16+
"GREETER_CLIENT_QOS",
17+
dynamic_config::DefaultAsJsonString{R"({
18+
"methods": {
19+
"__default__": {
20+
"timeout-ms": 10000
21+
}
22+
}
23+
})"},
24+
};
25+
1526
// A user-defined wrapper around api::GreeterServiceClient that provides
1627
// a simplified interface.
1728
GreeterClient::GreeterClient(api::GreeterServiceClient&& raw_client) : raw_client_(std::move(raw_client)) {}

samples/grpc_service/src/greeter_client.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ class GreeterClient final {
4949
using Client = GreeterClient;
5050

5151
/// [component]
52+
extern const dynamic_config::Key<ugrpc::client::ClientQos> kGreeterClientQos;
53+
5254
class GreeterClientComponent final : public ugrpc::client::SimpleClientComponent<Client> {
5355
public:
5456
static constexpr std::string_view kName = "greeter-client";
5557

5658
using Base = ugrpc::client::SimpleClientComponent<Client>;
5759

5860
GreeterClientComponent(const ::components::ComponentConfig& config, const ::components::ComponentContext& context)
59-
: Base(config, context) {}
61+
: Base(config, context, kGreeterClientQos) {}
6062

6163
using Base::GetClient;
6264
};

scripts/docs/en/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ and make sure that it builds and passes tests.
102102

103103
## Protocols
104104
* @ref scripts/docs/en/userver/grpc/grpc.md
105+
* @ref scripts/docs/en/userver/grpc/timeouts_retries.md
105106
* Middlewares
106107
* @ref scripts/docs/en/userver/grpc/server_middlewares.md
107108
* @ref scripts/docs/en/userver/grpc/server_middleware_implementation.md

scripts/docs/en/userver/grpc/grpc.md

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ See also:
1919
* Creating asynchronous gRPC clients and services;
2020
* Forwarding gRPC Core logs to userver logs;
2121
* Caching and reusing connections;
22-
* Timeouts;
22+
* @ref scripts/docs/en/userver/grpc/grpc_retries.md;
2323
* Collection of metrics on driver usage;
2424
* Cancellation support;
2525
* Automatic authentication using middlewares;
@@ -31,19 +31,32 @@ Generate and link a library from `.proto` schemas and link to it in your `CMakeL
3131

3232
@snippet samples/grpc_service/CMakeLists.txt add_grpc_library
3333

34-
`userver_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`.
34+
`userver_add_grpc_library` will link `userver::grpc` transitively and will generate the usual `.pb.h + .pb.cc` files.
35+
For service definitions, it will additionally generate asynchronous interfaces `foo_client.usrv.pb.hpp` and
36+
`foo_service.usrv.pb.hpp`.
3537

36-
To create gRPC clients in your microservice, register the provided ugrpc::client::ClientFactoryComponent and add the corresponding component section to the static config.
38+
To create gRPC clients in your microservice, register the provided @ref ugrpc::client::ClientFactoryComponent and add
39+
the corresponding component section to the static config.
40+
41+
To create gRPC services in your microservice, register the provided @ref ugrpc::server::ServerComponent and add the
42+
corresponding component section to the static config.
43+
44+
See @ref scripts/docs/en/userver/tutorial/grpc_service.md for a tutorial.
3745

38-
To create gRPC services in your microservice, register the provided ugrpc::server::ServerComponent and add the corresponding component section to the static config.
3946

4047
## gRPC clients
4148

4249
### Client creation
4350

44-
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.
51+
In a component constructor, find @ref ugrpc::client::ClientFactoryComponent and store a reference to its
52+
@ref ugrpc::client::ClientFactory. Using it, you can create gRPC clients of code-generated `YourServiceClient` types.
53+
54+
Client creation in an expensive operation! Either create them once at the server boot time or cache them. An automated
55+
solution for client creation and caching is the @ref ugrpc::client::SimpleClientComponent. It also allows to
56+
specify dynamic config for @ref ugrpc::client::ClientQos:
57+
58+
@snippet samples/grpc_service/src/greeter_client.hpp component
4559

46-
Client creation in an expensive operation! Either create them once at the server boot time or cache them.
4760

4861
### Client usage
4962

@@ -53,31 +66,37 @@ Typical steps include:
5366
* Fill the authentication metadata as necessary
5467
* Stream creation by calling a client method
5568
* Operations on the stream
56-
* Depending on the RPC kind, it is necessary to call `Finish` or `Read` until it returns `false` (otherwise the connection will close abruptly)
69+
* Depending on the RPC kind, it is necessary to call `Finish` or `Read` until it returns `false`
70+
(otherwise the connection will close abruptly)
5771

5872
Read the documentation on gRPC streams:
59-
* Single request, single response ugrpc::client::UnaryCall
60-
* Single request, response stream ugrpc::client::InputStream
61-
* Request stream, single response ugrpc::client::OutputStream
62-
* Request stream, response stream ugrpc::client::BidirectionalStream
73+
* Single request, single response @ref ugrpc::client::ResponseFuture
74+
* Single request, response stream @ref ugrpc::client::Reader
75+
* Request stream, single response @ref ugrpc::client::Writer
76+
* Request stream, response stream @ref ugrpc::client::ReaderWriter
6377

64-
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](https://grpc.github.io/grpc/core/md_doc_statuscodes.html) or all at once.
78+
On errors, exceptions from @ref userver/ugrpc/client/exceptions.hpp are thrown. It is recommended to catch them outside
79+
the entire stream interaction. You can catch exceptions for
80+
[specific gRPC error codes](https://grpc.github.io/grpc/core/md_doc_statuscodes.html) or all at once.
6581

6682
### Working with metadata
6783

68-
gRPC metadata allows you to send additional information along with requests and responses. Metadata consists of key-value pairs that are transmitted as HTTP/2 headers.
84+
gRPC metadata allows you to send additional information along with requests and responses. Metadata consists of
85+
key-value pairs that are transmitted as HTTP/2 headers.
6986

7087
#### Client-side metadata handling
7188

7289
##### Sending request metadata
7390

74-
To send metadata with a request, use @ref ugrpc::client::CallOptions and its @ref ugrpc::client::CallOptions::AddMetadata method:
91+
To send metadata with a request, use @ref ugrpc::client::CallOptions and its
92+
@ref ugrpc::client::CallOptions::AddMetadata method:
7593

7694
@snippet grpc/tests/metadata_test.cpp client_write_metadata
7795

7896
##### Receiving response metadata
7997

80-
Response metadata can be accessed through the @ref ugrpc::client::CallContext obtained from @ref ugrpc::client::ResponseFuture or stream objects:
98+
Response metadata can be accessed through the @ref ugrpc::client::CallContext obtained from
99+
@ref ugrpc::client::ResponseFuture or stream objects:
81100

82101
* **Reading initial metadata** - metadata sent by the server at the beginning of the response
83102

@@ -149,23 +168,26 @@ Use @ref ugrpc::client::MiddlewareBase to implement new middlewares.
149168

150169
#### List of standard client middlewares:
151170

152-
1. `grpc-client-logging` with component ugrpc::client::middlewares::log::Component - logs requests and responses.
153-
2. `grpc-client-deadline-propagation` with component ugrpc::client::middlewares::deadline_propagation::Component - activates
154-
@ref scripts/docs/en/userver/deadline_propagation.md.
155-
3. `grpc-client-baggage` with component ugrpc::client::middlewares::baggage::Component - passes request baggage to subrequests.
156-
3. `grpc-client-headers-propagator` with component ugrpc::client::middlewares::headers_propagator::Component - propagates headers.
157-
4. `grpc-client-middleware-testsuite` with component ugrpc::client::middlewares::testsuite::Component - supports testsuite errors thrown from the mockserver.
171+
1. `grpc-client-logging` with component ugrpc::client::middlewares::log::Component - logs requests and responses.
172+
2. `grpc-client-deadline-propagation` with component ugrpc::client::middlewares::deadline_propagation::Component - activates
173+
@ref scripts/docs/en/userver/deadline_propagation.md.
174+
3. `grpc-client-baggage` with component ugrpc::client::middlewares::baggage::Component - passes request baggage to subrequests.
175+
4. `grpc-client-headers-propagator` with component ugrpc::client::middlewares::headers_propagator::Component - propagates headers.
176+
5. `grpc-client-middleware-testsuite` with component ugrpc::client::middlewares::testsuite::Component - supports testsuite errors thrown from the mockserver.
177+
158178

159179
## gRPC services
160180

161181
### Service creation
162182

163-
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.
183+
A service implementation is a class derived from a code-generated `YourServiceBase` interface class. Each service
184+
method from the schema corresponds to a method of the interface class. If you don't override some of the methods,
185+
`UNIMPLEMENTED` error code will be reported for those.
164186

165187
To register your service:
166-
* Create a component that derives from ugrpc::server::ServiceComponentBase
188+
* Create a component that derives from @ref ugrpc::server::ServiceComponentBase
167189
* Store your service implementation instance inside the component
168-
* Call ugrpc::server::ServiceComponentBase::RegisterService in the component's constructor
190+
* Call @ref ugrpc::server::ServiceComponentBase::RegisterService in the component's constructor
169191
* Don't forget to register your service component.
170192

171193
### Service method handling
@@ -178,12 +200,14 @@ Each method receives:
178200
When using a server stream, always call `Finish` or `FinishWithError`. Otherwise the client will receive `UNKNOWN` error, which signifies an internal server error.
179201

180202
Read the documentation on gRPC streams:
181-
* Single request, single response ugrpc::server::UnaryCall
182-
* Request stream, single response ugrpc::server::InputStream
183-
* Single request, response stream ugrpc::server::OutputStream
184-
* Request stream, response stream ugrpc::server::BidirectionalStream
203+
* Single request, single response @ref ugrpc::server::Response
204+
* Request stream, single response @ref ugrpc::server::Reader + @ref ugrpc::server::Result
205+
* Single request, response stream @ref ugrpc::server::Writer + @ref ugrpc::server::StreamingResult
206+
* Request stream, response stream @ref ugrpc::server::ReaderWriter + @ref ugrpc::server::StreamingResult
185207

186-
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](https://grpc.github.io/grpc/core/md_doc_statuscodes.html) or all at once.
208+
On connection errors, exceptions from userver/ugrpc/server/exceptions.hpp are thrown. It is recommended not to catch
209+
them, leading to RPC interruption. You can catch exceptions for
210+
[specific gRPC error codes](https://grpc.github.io/grpc/core/md_doc_statuscodes.html) or all at once.
187211

188212
### TLS / SSL
189213

@@ -442,7 +466,7 @@ These are the metrics provided for each gRPC method:
442466
----------
443467
444468
@htmlonly <div class="bottom-nav"> @endhtmlonly
445-
⇦ @ref scripts/docs/en/userver/gdb_debugging.md | @ref scripts/docs/en/userver/grpc/server_middlewares.md ⇨
469+
⇦ @ref scripts/docs/en/userver/gdb_debugging.md | @ref scripts/docs/en/userver/grpc/timeouts_retries.md ⇨
446470
@htmlonly </div> @endhtmlonly
447471
448472
@example grpc-generic-proxy/src/proxy_service.hpp

0 commit comments

Comments
 (0)