Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC client retries #1187

Merged
merged 1 commit into from
Mar 8, 2021
Merged

gRPC client retries #1187

merged 1 commit into from
Mar 8, 2021

Conversation

JamesNK
Copy link
Member

@JamesNK JamesNK commented Feb 2, 2021

Fixes #1189

This PR adds support for gRPC retries. When retries are enabled, a wrapping call (either RetryCall or HedgingCall) is created that will manage making HTTP requests to the server. The wrapping call will create GrpcCall instances that will perform the HTTP request to the server.

  • All of the gRPC retries spec is supported.
  • GrpcCall is mostly unchanged.
  • RetryCall and HedgingCall (and their base type) handle retry logic, message buffering, throttling, etc. Once a gRPC call is commited then reposibility is handled back to it for returning a response.
  • Strongly typed ServiceConfig type for client configuration. Currently it is only ever manually created by the client, but in the future deserializing from JSON/Protobuf will be supported for populating it by a naming resolver.
  • Pay-for-play. gRPC calls that don't have retries enabled will use GrpcCall without performance impact of features required by retries.
  • Clear separate between retry logic and standard HTTP gRPC calls.

Other bugs fixed during this PR:


TODO

  • Hedging with exceeded deadline
  • Hedging with throttling
  • Retry limit configuration
  • Buffer limit configuration
  • Refactor configuration objects to improve intellisense
  • Handle ResponseStream.MoveNext cancellation

Work in progress on https://github.com/grpc/proposal/blob/master/A6-client-retries.md

var serviceConfig = new ServiceConfig
{
    MethodConfigs =
    {
        new MethodConfig
        {
            Names = { Name.AllServices },
            RetryPolicy = new RetryThrottlingPolicy
            {
                MaxAttempts = 5,
                InitialBackoff = TimeSpan.FromSeconds(1),
                RetryableStatusCodes = { StatusCode.Unavailable }
            }
        }
    }
};

var channel = GrpcChannel.Create("https://localhost:5001", new GrpcChannelOptions
{
    ServiceConfig = serviceConfig
});
var client = new Greet.GreeterClient(channel);

// Make gRPC call with retries
var reply = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
Console.WriteLine(reply.Message);

@JamesNK JamesNK changed the title [NO MERGE] gRPC client retry [NO MERGE] gRPC client retries Feb 2, 2021
@JamesNK JamesNK marked this pull request as ready for review February 10, 2021 06:15
@JamesNK JamesNK changed the title [NO MERGE] gRPC client retries gRPC client retries Feb 16, 2021
@JamesNK JamesNK force-pushed the jamesnk/retries branch 2 times, most recently from e549c80 to 349c91f Compare February 17, 2021 21:52
Copy link

@Tratcher Tratcher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lazy config model doesn't seem like a good fit here. It results in a lot of per-request validation and parsing (sometimes repeatedly per request) that could have been done once up front when creating the channel.

src/Grpc.Net.Client/Internal/Retry/DeadlineGrpcCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/RetryCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/RetryCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/RetryCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/HedgingCall.cs Outdated Show resolved Hide resolved
@JamesNK
Copy link
Member Author

JamesNK commented Feb 19, 2021

Copy link
Contributor

@JunTaoLuo JunTaoLuo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor questions

src/Grpc.Net.Client/GrpcChannelOptions.cs Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/RetryCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/RetryCall.cs Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Internal/Retry/HedgingCall.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@JunTaoLuo JunTaoLuo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good though I wouldn't be surprised if there are some synchronization corner cases that we missed. Given that the features added are marked with experimental status, I'm okay with merging the changes and fix issues that come up.

Let's wait for @jtattermusch to take a look as well.

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments, but overall LGTM. Thanks for implementing this!

src/Grpc.Net.Client/Internal/GrpcCall.cs Outdated Show resolved Hide resolved
Directory.Build.props Outdated Show resolved Hide resolved
src/Grpc.Net.Client/Configuration/HedgingPolicy.cs Outdated Show resolved Hide resolved
test/FunctionalTests/Client/HedgingTests.cs Show resolved Hide resolved
test/Shared/TestHelpers.cs Outdated Show resolved Hide resolved
@JamesNK JamesNK merged commit 3765363 into grpc:master Mar 8, 2021
@JamesNK JamesNK deleted the jamesnk/retries branch March 8, 2021 22:18
@JamesNK
Copy link
Member Author

JamesNK commented Mar 8, 2021

🍰 🥳 🎈 🎉

This was referenced Mar 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add gRPC retry support
6 participants