Skip to content

Commit

Permalink
update http client timeout for scope sync (#4822)
Browse files Browse the repository at this point in the history
HttpClient has default timeout to 100seconds and when it times out it throws TaskCanceledException and call is not retried.
This change is setting timeout to 5 min for http client and uses TimeoutAfter which throws TimeoutException
  • Loading branch information
ancaantochi authored Apr 8, 2021
1 parent 8988456 commit 69d8c0c
Showing 1 changed file with 8 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class NestedDeviceScopeApiClient : IDeviceScopeApiClient

const string NestedApiVersion = "2020-06-30-preview";

static readonly TimeSpan OperationTimeout = TimeSpan.FromMinutes(2);
// Timeout set to HttpClient is > OperationTimeout because HttpClient throws TaskCanceledException when it timeouts and retry policy won't retry it in that case
static readonly TimeSpan HttpOperationTimeout = TimeSpan.FromMinutes(5);

static readonly ITransientErrorDetectionStrategy TransientErrorDetectionStrategy = new ErrorDetectionStrategy();

static readonly RetryStrategy TransientRetryStrategy =
Expand Down Expand Up @@ -124,7 +128,7 @@ async Task<ScopeResult> GetIdentityOnBehalfOfWithRetry(Uri uri, string deviceId,
try
{
return await ExecuteWithRetry(
() => this.GetIdentityOnBehalfOfInternalAsync(uri, deviceId, moduleId, onBehalfOfDevice),
() => this.GetIdentityOnBehalfOfInternalAsync(uri, deviceId, moduleId, onBehalfOfDevice).TimeoutAfter(OperationTimeout),
Events.RetryingGetIdentities,
this.retryStrategy);
}
Expand All @@ -143,7 +147,7 @@ async Task<ScopeResult> GetIdentitiesInTargetScopeWithRetry(Uri uri, Option<stri
try
{
return await ExecuteWithRetry(
() => this.GetIdentitiesInTargetScopeInternalAsync(uri, continuation),
() => this.GetIdentitiesInTargetScopeInternalAsync(uri, continuation).TimeoutAfter(OperationTimeout),
Events.RetryingGetIdentities,
this.retryStrategy);
}
Expand All @@ -159,6 +163,7 @@ async Task<ScopeResult> GetIdentityOnBehalfOfInternalAsync(Uri uri, string devic
HttpClient client = this.proxy
.Map(p => new HttpClient(new HttpClientHandler { Proxy = p }, disposeHandler: true))
.GetOrElse(() => new HttpClient());
client.Timeout = HttpOperationTimeout;
using (var msg = new HttpRequestMessage(HttpMethod.Post, uri))
{
// Get the auth-chain for the Edge we're acting OnBehalfOf
Expand Down Expand Up @@ -190,6 +195,7 @@ async Task<ScopeResult> GetIdentitiesInTargetScopeInternalAsync(Uri uri, Option<
HttpClient client = this.proxy
.Map(p => new HttpClient(new HttpClientHandler { Proxy = p }, disposeHandler: true))
.GetOrElse(() => new HttpClient());
client.Timeout = HttpOperationTimeout;
using (var msg = new HttpRequestMessage(HttpMethod.Post, uri))
{
// Get the auth-chain for the target device
Expand Down

0 comments on commit 69d8c0c

Please sign in to comment.