public void SetUp() { _loggerMock = new Mock <ILogger>(); _retryHandlerOptionsMock = new Mock <IRetryHandlerOptions>(); _sut = new DefaultRetryHandler(_retryHandlerOptionsMock.Object, _loggerMock.Object); _count = 0; }
public LoadBalancerCommand(ILoadBalancer loadBalancer, IServerStatusCollector collector, IRetryHandler retryHandler, Server server) { RetryHandler = retryHandler; LoadBalancer = loadBalancer; Collector = collector ?? new DefaultServerStatusCollector(); _server = server; }
public AlopeykClient( Uri remoteServiceUri, string token, HttpClient httpClient, IJsonSerializer jsonSerializer, IRetryHandler retryHandler ) { if (remoteServiceUri is null) { throw new ArgumentNullException(nameof(remoteServiceUri)); } if (httpClient is null) { throw new ArgumentNullException(nameof(httpClient)); } if (jsonSerializer is null) { throw new ArgumentNullException(nameof(jsonSerializer)); } RemoteServiceUri = remoteServiceUri; Token = token; HttpClient = httpClient; JsonSerializer = jsonSerializer; RetryHandler = retryHandler ?? Alopeyk.Net.RetryHandler.NoRetry.Value; }
/// <summary> /// Initializes a new instance of the <see cref="SessionPool"/> class. /// </summary> /// <param name="sessionCreator">The method to create a new underlying QLDB session. The operation can be cancelled.</param> /// <param name="retryHandler">Handling the retry logic of the execute call.</param> /// <param name="maxConcurrentTransactions">The maximum number of sessions that can be created from the pool at any one time.</param> /// <param name="logger">Logger to be used by this.</param> public SessionPool(Func <CancellationToken, Task <Session> > sessionCreator, IRetryHandler retryHandler, int maxConcurrentTransactions, ILogger logger) { this.sessionPool = new BlockingCollection <QldbSession>(maxConcurrentTransactions); this.poolPermits = new SemaphoreSlim(maxConcurrentTransactions, maxConcurrentTransactions); this.sessionCreator = sessionCreator; this.retryHandler = retryHandler; this.logger = logger; }
public SpotifyClientConfig WithRetryHandler(IRetryHandler retryHandler) { return(new SpotifyClientConfig( BaseAddress, Authenticator, JSONSerializer, HTTPClient, retryHandler, HTTPLogger, DefaultPaginator )); }
/// <summary> /// Determine whether the feed is public or private. /// </summary> /// <param name="feedUrl">Feed url to test</param> /// <returns>True if the feed is public, false if it is private, and null if it was not possible to determine.</returns> /// <remarks> /// Do an unauthenticated GET on the feed URL. If it succeeds, the feed is not public. /// If it fails with a 4* error, assume it is internal. /// </remarks> public static async Task <bool?> IsFeedPublicAsync( string feedUrl, HttpClient httpClient, TaskLoggingHelper log, IRetryHandler retryHandler) { bool?isPublic = null; bool success = await retryHandler.RunAsync(async attempt => { try { HttpResponseMessage response = await httpClient.GetAsync(feedUrl); if (response.IsSuccessStatusCode) { isPublic = true; return(true); } else if (response.StatusCode >= (System.Net.HttpStatusCode) 400 && response.StatusCode < (System.Net.HttpStatusCode) 500) { isPublic = false; return(true); } else { // Don't know for certain, retry return(false); } } catch (Exception e) { log.LogMessage(MessageImportance.Low, $"Unexpected exception {e.Message} when attempting to determine whether feed is internal."); return(false); } }); if (!success) { // We couldn't determine anything. We'd be unlikely to be able to push to this feed either, // since it's 5xx'ing. log.LogError($"Unable to determine whether '{feedUrl}' is public or internal."); } return(isPublic); }
public LoadBalancerContext(ILoadBalancer loadBalancer, IRetryHandler retryHandler, string vipAddress) : this(loadBalancer, vipAddress) { RetryHandler = retryHandler; }
/// <summary> /// Initializes a new instance of the <see cref="SessionPool"/> class. /// </summary> /// <param name="sessionCreator">The method to create a new underlying QLDB session.</param> /// <param name="retryHandler">Handling the retry logic of the execute call.</param> /// <param name="maxConcurrentTransactions">The maximum number of sessions that can be created from the pool at any one time.</param> /// <param name="logger">Logger to be used by this.</param> public SessionPool(Func <Task <Session> > sessionCreator, IRetryHandler retryHandler, int maxConcurrentTransactions, ILogger logger) : this(ct => sessionCreator(), retryHandler, maxConcurrentTransactions, logger) { }
public SubmitCompletionAsyncJob(ILogger <SubmitCompletionAsyncJob> logger, IRetryHandler retryHandler) { _logger = logger; _retryHandler = retryHandler; }
/// <summary> /// Determine whether a local package is the same as a package on an AzDO feed. /// </summary> /// <param name="localPackageFullPath"></param> /// <param name="packageContentUrl"></param> /// <param name="client"></param> /// <param name="log"></param> /// <param name="retryHandler"></param> /// <returns></returns> /// <remarks> /// Open a stream to the local file and an http request to the package. There are a couple possibilities: /// - The returned headers include a content MD5 header, in which case we can /// hash the local file and just compare those. /// - No content MD5 hash, and the streams must be compared in blocks. This is a bit trickier to do efficiently, /// since we do not necessarily want to read all bytes if we can help it. Thus, we should compare in blocks. However, /// the streams make no guarantee that they will return a full block each time when read operations are performed, so we /// must be sure to only compare the minimum number of bytes returned. /// </remarks> public static async Task <PackageFeedStatus> CompareLocalPackageToFeedPackage( string localPackageFullPath, string packageContentUrl, HttpClient client, TaskLoggingHelper log, IRetryHandler retryHandler) { log.LogMessage($"Getting package content from {packageContentUrl} and comparing to {localPackageFullPath}"); PackageFeedStatus result = PackageFeedStatus.Unknown; bool success = await retryHandler.RunAsync(async attempt => { try { using (Stream localFileStream = File.OpenRead(localPackageFullPath)) using (HttpResponseMessage response = await client.GetAsync(packageContentUrl)) { response.EnsureSuccessStatusCode(); // Check the headers for content length and md5 bool md5HeaderAvailable = response.Headers.TryGetValues("Content-MD5", out var md5); bool lengthHeaderAvailable = response.Headers.TryGetValues("Content-Length", out var contentLength); if (lengthHeaderAvailable && long.Parse(contentLength.Single()) != localFileStream.Length) { log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different length than remote package '{packageContentUrl}'."); result = PackageFeedStatus.ExistsAndDifferent; return(true); } if (md5HeaderAvailable) { var localMD5 = AzureStorageUtils.CalculateMD5(localPackageFullPath); if (!localMD5.Equals(md5.Single(), StringComparison.OrdinalIgnoreCase)) { log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different MD5 hash than remote package '{packageContentUrl}'."); } result = PackageFeedStatus.ExistsAndDifferent; return(true); } const int BufferSize = 64 * 1024; // Otherwise, compare the streams var remoteStream = await response.Content.ReadAsStreamAsync(); var streamsMatch = await GeneralUtils.CompareStreamsAsync(localFileStream, remoteStream, BufferSize); result = streamsMatch ? PackageFeedStatus.ExistsAndIdenticalToLocal : PackageFeedStatus.ExistsAndDifferent; return(true); } } // String based comparison because the status code isn't exposed in HttpRequestException // see here: https://github.com/dotnet/runtime/issues/23648 catch (HttpRequestException e) { if (e.Message.Contains("404 (Not Found)")) { result = PackageFeedStatus.DoesNotExist; return(true); } // Retry this. Could be an http client timeout, 500, etc. return(false); } }); return(result); }
public DefaultFileSystemService(ILogger <IFileService> logger, IRetryHandler retryHandler, IRetryHandlerOptions retryHandlerOptions) { _logger = logger; _retryHandler = retryHandler; _retryHandlerOptions = retryHandlerOptions; }