Skip to content

RPC timeouts and retry loops across services #4926

@coryan

Description

@coryan

The google::cloud::bigtable::RPCRetryPolicy classes have special member functions to setup a timeout:

/**
* Update the ClientContext for the next call.
*/
virtual void Setup(grpc::ClientContext& context) const = 0;

void LimitedTimeRetryPolicy::Setup(grpc::ClientContext& context) const {
if (context.deadline() >= impl_.deadline()) {
context.set_deadline(impl_.deadline());
}
}

This is used in the synchronous retry loop, e.g.:

while (true) {
grpc::ClientContext client_context;
rpc_policy->Setup(client_context);
backoff_policy->Setup(client_context);
metadata_update_policy_.Setup(client_context);
status = client_->MutateRow(&client_context, request, &response);

But not in the asynchronous retry loop:

static void StartIteration(std::shared_ptr<RetryAsyncUnaryRpc> self,
CompletionQueue cq) {
auto context = absl::make_unique<grpc::ClientContext>();
cq.MakeUnaryRpc(self->async_call_, self->request_, std::move(context))

That asynchronous retry loop is used in spanner too, and the RetryPolicy for spanner does not have a Setup() member function. Furthermore, the same retry policy class is used in storage, where we would't want to introduce it (because that would create an unwanted dependency on gRPC).

We need a cleaner way to setup per-RPC timeouts across all services, with good support for REST, and we need to use that on the asynchronous and synchronous loops.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: cleanupAn internal cleanup or hygiene concern.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions