I'm using a policy to retry a call in case it fails due to certain reason.
AsyncRetryPolicy<HttpResponseMessage> GetPolicy() => Policy
.HandleResult<HttpResponseMessage>(a => a.StatusCode is HttpStatusCode.Poof or ...)
.WaitAndRetryAsync(stubborness, bideTime,
async (response, timespan, context) => { ... });
It performs just as expected for GetAsync(...)
, PostAsync(...)
, PutAsync(...)
.
using HttpResponseMessage response = await RetryPolicy
.ExecuteAsync(() => Client.PutAsync(url, content));
However, it doesn't work well with the general SendAsync(...)
. In case the call fails, the retry kicks in but then crashes reporting an exception that the request already has been dispatched and can't be reused. While using the verb specific methods, a new request is constructed each time. Using the general one and passing a custom, pre-created request, will use it, hence stumbling. An important detail is that I need to alter the headers for each call.
HttpRequestMessage request = new(HttpMethod.Put, new Uri(url));
request.Content = new StringContent(GetJson(code), Encoding.UTF8, "text/json");
request.Headers.Add("tenant", GetId(code));
using HttpResponseMessage response = await RetryPolicy
.ExecuteAsync(() => Client.SendAsync(request));
I have tried to provide the call specific header for each call while using the specialized methods. That failed as I haven't found any overload doing that.
I have tried altering default headers on the client for each call. That failed due to asunchronicity and wrong header being using during certain calls.
I have tried contructing a specialized client with the ID as a default header. That failed due to the gianormous number of different clients I'd end up with.
I have tried creating a new request and swoop it in to the retry. That failed because I haven't found a reference to the HTTP context nor the old request anywhere in the WaitAndRetryAsync(...)
handler.
Is there a way to dance around it?
I've seen articles suggesting that SendAsync(...)
isn't the most suitable choice if one needs to tampter with headers. However, I'm stubborn as duck and want to determine whether it's possible, not only if it's smoothly possible.