Here's an example of how to retry 3 times using an expanding backoff strategy (waits a bit longer before each successive retry).
Public Async Function PostAsync(Of TRequest, TResponse)(content As TRequest) As Task(Of TResponse)
Dim deserializedResponse As TResponse = Nothing
Try
If _client.BaseAddress Is Nothing Then
Throw New InvalidOperationException("BaseAddress is not set.")
End If
Dim retriesLeft As Integer = 3
Dim attempt As Integer = 0
Do
attempt += 1
' Build the request fresh each attempt
Dim json As String = JsonConvert.SerializeObject(content)
Using request As New HttpRequestMessage(HttpMethod.Post)
If request.RequestUri Is Nothing Then
Throw New InvalidOperationException("RequestUri is not set.")
End If
Dim fullUrl As New Uri(_client.BaseAddress, request.RequestUri)
request.Headers.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
' GenerateAuthorizationHeader is implemented elsewhere
Dim authHeaderValue As String = GenerateAuthorizationHeader()
request.Headers.Authorization = New AuthenticationHeaderValue("OAuth", authHeaderValue)
request.Content = New StringContent(json, Encoding.UTF8, "application/json")
Using response As HttpResponseMessage = Await _client.SendAsync(request)
If response.IsSuccessStatusCode Then
Dim compressedBase64 As String = Await response.Content.ReadAsStringAsync()
Dim responseObject As JObject = JsonConvert.DeserializeObject(Of JObject)(compressedBase64)
If responseObject Is Nothing Then
Throw New NSApiClientException("Response was null.", HttpStatusCode.InternalServerError)
End If
Dim base64Data As String = CStr(responseObject("compressedData"))
Dim compressedBytes As Byte() = Convert.FromBase64String(base64Data)
Dim decompressedJson As String = DecompressGzip(compressedBytes)
deserializedResponse = JsonConvert.DeserializeObject(Of TResponse)(decompressedJson)
Exit Do
Else
Dim status As HttpStatusCode = response.StatusCode
Dim responseBody As String = Await response.Content.ReadAsStringAsync()
If status = HttpStatusCode.InternalServerError AndAlso retriesLeft > 0 Then
retriesLeft -= 1
' simple linear backoff
Await Task.Delay(TimeSpan.FromMilliseconds(250 * attempt))
Continue Do
End If
Throw New Exception(
$"Unexpected status code: {status}. I'm sorry, I tried {attempt} times and it didn't work out",
status,
fullUrl.ToString(),
responseBody
)
End If
End Using
End Using
Loop
Catch ex As Exception
' Log the exception details
BRApi.ErrorLog.LogError(_si, XFErrorLevel.Error, ex.Message)
End Try
Return deserializedResponse
End Function