Skip to content

Commit 8d63954

Browse files
committed
Refactored, use HttpStatusCode enum for retriable errors and better naming
1 parent 58e95c7 commit 8d63954

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

src/SendGrid/Reliability/RetryDelegatingHandler.cs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Net;
56
using System.Net.Http;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -11,7 +12,14 @@
1112
/// </summary>
1213
public class RetryDelegatingHandler : DelegatingHandler
1314
{
14-
private static readonly List<int> RetriableStatusCodes = new List<int>() { 500, 502, 503, 504 };
15+
private static readonly List<HttpStatusCode> RetriableServerErrorStatusCodes =
16+
new List<HttpStatusCode>()
17+
{
18+
HttpStatusCode.InternalServerError,
19+
HttpStatusCode.BadGateway,
20+
HttpStatusCode.ServiceUnavailable,
21+
HttpStatusCode.GatewayTimeout
22+
};
1523

1624
private readonly ReliabilitySettings settings;
1725

@@ -26,6 +34,11 @@ public RetryDelegatingHandler(ReliabilitySettings settings)
2634
{
2735
}
2836

37+
/// <summary>
38+
/// Initializes a new instance of the <see cref="RetryDelegatingHandler"/> class.
39+
/// </summary>
40+
/// <param name="innerHandler">A HttpMessageHandler instance to set as the innner handler</param>
41+
/// <param name="settings">A ReliabilitySettings instance</param>
2942
public RetryDelegatingHandler(HttpMessageHandler innerHandler, ReliabilitySettings settings)
3043
: base(innerHandler)
3144
{
@@ -41,12 +54,13 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
4154

4255
HttpResponseMessage responseMessage = null;
4356

44-
var waitFor = settings.RetryInterval;
4557
var numberOfAttempts = 0;
4658
var sent = false;
4759

4860
while (!sent)
4961
{
62+
var waitFor = this.GetNextWaitInterval(numberOfAttempts);
63+
5064
try
5165
{
5266
responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
@@ -78,30 +92,33 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
7892

7993
await Task.Delay(waitFor).ConfigureAwait(false);
8094
}
81-
82-
waitFor = GetNextWaitInterval(numberOfAttempts);
8395
}
8496

8597
return responseMessage;
8698
}
8799

88100
private static void ThrowHttpRequestExceptionIfResponseCodeCanBeRetried(HttpResponseMessage responseMessage)
89101
{
90-
int statusCode = (int)responseMessage.StatusCode;
91-
92-
if (RetriableStatusCodes.Contains(statusCode))
102+
if (RetriableServerErrorStatusCodes.Contains(responseMessage.StatusCode))
93103
{
94-
throw new HttpRequestException(string.Format("Http status code '{0}' indicates server error", statusCode));
104+
throw new HttpRequestException(string.Format("Http status code '{0}' indicates server error", responseMessage.StatusCode));
95105
}
96106
}
97107

98108
private TimeSpan GetNextWaitInterval(int numberOfAttempts)
99109
{
100-
var interval = this.settings.RetryInterval.TotalMilliseconds + (Math.Pow(2, numberOfAttempts) * 1000);
110+
var randomDelay = this.random.Next(0, 500);
111+
112+
if (numberOfAttempts == 0)
113+
{
114+
return TimeSpan.FromMilliseconds(this.settings.RetryInterval.TotalMilliseconds + randomDelay);
115+
}
116+
117+
var exponentialIncrease = Math.Pow(2, numberOfAttempts) * 1000;
101118

102-
var randomDelay = this.random.Next(0, 1000);
119+
var actualIncrease = TimeSpan.FromMilliseconds(this.settings.RetryInterval.TotalMilliseconds + exponentialIncrease + randomDelay);
103120

104-
return TimeSpan.FromMilliseconds(interval + randomDelay);
121+
return actualIncrease;
105122
}
106123
}
107124
}

0 commit comments

Comments
 (0)