Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 41 additions & 27 deletions docs/specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,12 @@ retryable and not-retryable:
The server MUST indicate retryable errors using code
[Unavailable](https://godoc.org/google.golang.org/grpc/codes) and MAY supply
additional
[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails)
using
[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40)
containing 0 value of RetryDelay. Here is a sample Go code to illustrate:
[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails).
Here is a sample Go code to illustrate:

```go
// Do this on server side.
st, err := status.New(codes.Unavailable, "Server is unavailable").
WithDetails(&errdetails.RetryInfo{RetryDelay: &duration.Duration{Seconds: 0}})
st, err := status.New(codes.Unavailable, "Server is unavailable")
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -313,8 +310,13 @@ error with code [Unavailable](https://godoc.org/google.golang.org/grpc/codes)
and MAY supply additional
[details via status](https://godoc.org/google.golang.org/grpc/status#Status.WithDetails)
using
[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40).
Here is a snippet of sample Go code to illustrate:
[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40)
or [through the gRPC metadata key `grpc-retry-pushback-ms`](https://github.com/grpc/proposal/blob/master/A6-client-retries.md#pushback).

Some clients may only respect one of these pushback mechanisms, so it's recommended for the server to implement both if it's
critical that it be respected.

Here is a snippet of sample Go code to illustrate using `RetryInfo`:

```go
// Do this on the server side.
Expand All @@ -339,29 +341,41 @@ Here is a snippet of sample Go code to illustrate:
}
}
```
Here is a snippet of sample Python code to illustrate using `grpc-retry-pushback-ms`:

```python
# Do this on the server side.
context.set_trailing_metadata(
(
(
"grpc-retry-pushback-ms",
"5000", # 5 seconds
),
)
)
context.abort(StatusCode.UNAVAILABLE, "")

When the client receives this signal, it SHOULD follow the recommendations
outlined in documentation for
[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40):
...

```
// Describes when the clients can retry a failed request. Clients could ignore
// the recommendation here or retry when this information is missing from the error
// responses.
//
// It's always recommended that clients should use exponential backoff when
// retrying.
//
// Clients should wait until `retry_delay` amount of time has passed since
// receiving the error response before retrying. If retrying requests also
// fail, clients should use an exponential backoff scheme to increase gradually
// the delay between retries based on `retry_delay` until either a maximum
// number of retries has been reached, or a maximum retry delay cap has been
// reached.
# On the client side use gRPC retry config: https://grpc.io/docs/guides/retry/, which will automatically parse this header
# and handle all backoff and retry logic.
# Or manually parse the header:

pushback = dict(error.trailing_metadata()).get("grpc-retry-pushback-ms")
if pushback is not None:
wait_period = int(pushback)
```

The value of `retry_delay` is determined by the server and is implementation
dependant. The server SHOULD choose a `retry_delay` value that is big enough to
When the client receives this signal, it SHOULD follow the recommendations
outline in the documentation for [`grpc-retry-pushback-ms`](https://github.com/grpc/proposal/blob/master/A6-client-retries.md#pushback)
or outlined in documentation for
[RetryInfo](https://github.com/googleapis/googleapis/blob/6a8c7914d1b79bd832b5157a09a9332e8cbd16d4/google/rpc/error_details.proto#L40),
depending on which one is present. If both are present they should be the same, and either can be used. It is acceptable for
client's to only look for one of these values, server's should set both to be certain that it will
be respected.

The value of `retry_delay`/`grpc-retry-pushback-ms` is determined by the server and is implementation
dependant. The server SHOULD choose a `retry_delay`/`grpc-retry-pushback-ms` value that is big enough to
give the server time to recover yet is not too big to cause the client to drop
data while being throttled.

Expand Down
Loading