protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { SessionTokenContainer sessionTokenContainer = _asyncLocalSessionTokenContainer.Value; if (sessionTokenContainer == null) { throw new InvalidOperationException($"{nameof(SessionTokenContainer)} has not been set for the execution context"); } string latestValue = sessionTokenContainer.SessionToken; if (!string.IsNullOrEmpty(latestValue)) { request.Headers.TryAddWithoutValidation("x-ms-session-token", latestValue); } request.Headers.TryAddWithoutValidation("x-ms-consistency-level", "Session"); if (request.Content != null) { await request.Content.LoadIntoBufferAsync(); } HttpResponseMessage response = await _polly.ExecuteAsync(async() => await base.SendAsync(request, cancellationToken)); if (response.Headers.TryGetValues("x-ms-session-token", out var tokens)) { sessionTokenContainer.SessionToken = tokens.SingleOrDefault(); } return(response); }
public SessionMessageHandler(HttpMessageHandler innerHandler, SessionTokenContainer sessionTokenContainer) : base(innerHandler) { EnsureArg.IsNotNull(sessionTokenContainer, nameof(sessionTokenContainer)); _sessionTokenContainer = sessionTokenContainer; _polly = Policy.Handle <HttpRequestException>(x => { if (x.InnerException is IOException || x.InnerException is SocketException) { return(true); } return(false); }) .OrResult <HttpResponseMessage>(message => (int)message.StatusCode == 429) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); }