/// <summary> /// Create a new retry configuration. /// </summary> /// <param name="baseDelayMs">The base delay (milliseconds) used to calculate the time before making another request attempt.</param> /// <param name="maxRetries">The maximum number of attempts to make before cancelling the request task.</param> /// <param name="listener">A callback that is invoked before a new retry attempt is made.</param> /// <param name="jitter">/// The jitter algorithm used to apply randomness to the retry delay.</param> public RetryConfiguration(int baseDelayMs, int maxRetries, RetryListener listener, Jitter jitter) { BaseDelayMs = baseDelayMs; RetryListener = listener; MaxAttempts = maxRetries; Jitter = jitter; }
public async void RetryConfiguration_PastMaxRetries_ThrowsTaskCancelledException() { var adapterSchedule = new TransientAdapterResponseType[4] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); int lastNumRetry = 3; RetryListener retryListener = (int numRetry, Retry retry) => { lastNumRetry = numRetry; }; var config = new RetryConfiguration(baseDelayMs: 500, maxRetries: 3, retryListener); client.GlobalRetryConfiguration = config; Task <ISession> sessionTask = client.AuthenticateCustomAsync("test_id"); await Assert.ThrowsAsync <TaskCanceledException>(async() => await sessionTask); Assert.Equal(3, lastNumRetry); }
public async void RetryConfiguration_FiveRetries_RetriesExactlyFiveTimes() { var adapterSchedule = new TransientAdapterResponseType[6] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.ServerOk }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); int lastNumRetry = -1; RetryListener retryListener = (int numRetry, Retry retry) => { lastNumRetry = numRetry; }; var config = new RetryConfiguration(baseDelayMs: 1, maxRetries: 5, retryListener); client.GlobalRetryConfiguration = config; Task <ISession> sessionTask = client.AuthenticateCustomAsync("test_id"); ISession session = await sessionTask; Assert.NotNull(session); Assert.Equal(5, lastNumRetry); }
public async void RetryConfiguration_Delay_ExpectedExponentialTimes() { var adapterSchedule = new TransientAdapterResponseType[4] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.ServerOk }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); var retries = new List <Retry>(); RetryListener retryListener = (int numRetry, Retry retry) => { retries.Add(retry); }; var config = new RetryConfiguration(baseDelayMs: 10, maxRetries: 3, retryListener); client.GlobalRetryConfiguration = config; Task <ISession> sessionTask = client.AuthenticateCustomAsync("test_id"); ISession session = await sessionTask; Assert.NotNull(session); Assert.Equal(10, retries[0].ExponentialBackoff); Assert.Equal(20, retries[1].ExponentialBackoff); Assert.Equal(40, retries[2].ExponentialBackoff); }
public async void RetryConfiguration_OverrideSet_OverridesGlobal() { var adapterSchedule = new TransientAdapterResponseType[4] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.ServerOk }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); int lastNumRetry = -1; RetryListener retryListener = (int numRetry, Retry retry) => { lastNumRetry = numRetry; }; var globalConfig = new RetryConfiguration(baseDelayMs: 10, maxRetries: 1, retryListener); client.GlobalRetryConfiguration = globalConfig; var localConfig = new RetryConfiguration(baseDelayMs: 10, maxRetries: 3, retryListener); var session = await client.AuthenticateCustomAsync("test_id", null, true, null, localConfig); Assert.NotNull(session); Assert.Equal(3, lastNumRetry); }
public async void TestCancelDuringBackoff() { var adapterSchedule = new TransientAdapterResponseType[3] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); var canceller = new CancellationTokenSource(); RetryListener retryListener = (int numRetry, Retry retry) => { canceller.Cancel(); }; Task <ISession> authTask = client.AuthenticateCustomAsync("test_id", null, true, null, new RetryConfiguration(100, 2, retryListener), canceller.Token); await Assert.ThrowsAsync <TaskCanceledException>(async() => await authTask); }
public async void RetryConfiguration_Delay_ExpectedDelays() { var adapterSchedule = new TransientAdapterResponseType[3] { TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, TransientAdapterResponseType.TransientError, }; var adapter = new TransientExceptionHttpAdapter(adapterSchedule); var client = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter); var retries = new List <Retry>(); RetryListener retryListener = (int numRetry, Retry retry) => { retries.Add(retry); }; var config = new RetryConfiguration(baseDelayMs: 10, maxRetries: 3, retryListener); client.GlobalRetryConfiguration = config; DateTime timeBeforeRequest = DateTime.Now; DateTime timeAfterRequest = default(DateTime); try { await client.AuthenticateCustomAsync("test_id"); } catch { timeAfterRequest = DateTime.Now; } int expectedElapsedTime = retries.Sum(retry => retry.JitterBackoff); int actualElapsedTime = (int)(timeAfterRequest - timeBeforeRequest).TotalMilliseconds; // actual will be slightly higher due to cpu elapsed time Assert.True(expectedElapsedTime < actualElapsedTime); }
/// <summary> /// Create a new retry configuration. /// </summary> /// <param name="baseDelayMs">The base delay (milliseconds) used to calculate the time before making another request attempt.</param> /// <param name="maxRetries">The maximum number of attempts to make before cancelling the request task.</param> /// <param name="listener">A callback that is invoked before a new retry attempt is made.</param> public RetryConfiguration(int baseDelayMs, int maxRetries, RetryListener listener) : this(baseDelayMs, maxRetries, listener, RetryJitter.FullJitter) { }