googleapis / google-api-dotnet-client

Google APIs Client Library for .NET
https://developers.google.com/api-client-library/dotnet
Apache License 2.0
1.35k stars 525 forks source link

BackOffHandler to honor retryAfter value in case of rateLimitExceeded #2715

Open SangeethaJanakiraman opened 7 months ago

SangeethaJanakiraman commented 7 months ago

We are using BackoffHandler https://github.com/googleapis/google-api-dotnet-client/blob/55e00d18f4024a44f7007a3dbfaf6fcba4ed67f5/Src/Support/Google.Apis.Core/Http/BackOffHandler.cs#L31 to retry the errors like ratelimitExceeded / userRateLimitExceeded.

But by default, it computes time to wait using exponential backoff logic. Google API sometimes gives the retryAfter value in case of 429 http status codes. Ex. The service gmail has thrown an exception. HttpStatusCode is 429. User-rate limit exceeded. Retry after 2024-01-10T23:55:00.392Z

Is it possible to honor this Retryafter value in backOffHandler ? Else we need to have multiple UnsuccessfulResponse handlers -

  1. Default BackoffHandler for 429 or other codes without retryAfter
  2. RetryAfterHandler - custom implementation to honor retry value to wait.

Please confirm if this enhancement can be possible from library side.

amanda-tarafa commented 7 months ago

We'll look into this, it's certainly a reasonable request. We'll update here when we know more.

SangeethaJanakiraman commented 4 weeks ago

Hi, any update on this yet?

Also, I have one more query.

Since all our retries are within SendAsync method, sometimes the HttpTimeout happens before we attempt all retries. For ex. set HttpTimeout to 3 mins and numRetries to 10. With exponential backoff logic, the cumulative wait time can exceed 3 mins and before we use all our retry attempts, HttpTimeout exception is thrown.

Currently I am setting large value for Http timeouts to avoid the above case. Any other suggestion ?

amanda-tarafa commented 3 weeks ago

This request is still in our backlog. We'll get to i eventually, but still, we don't have an ETA.

AS for your question, yes, you need to set a timeout value that allows for all the retry attempts you have configured. You don't have to set the timeout "very large", just "large enough" that retry attempts can be honored.