private void TestBackoffMaxLevel(IBackoffStrategy backoffStrategy) { for (var maxBackoff = 0; maxBackoff <= 16; maxBackoff++) { for (var multiplier = 1; multiplier <= 16; multiplier++) { var config = new NsqConfig { MaxBackoffDuration = TimeSpan.FromMilliseconds(maxBackoff), BackoffMultiplier = TimeSpan.FromMilliseconds(multiplier) }; config.Validate(); var expectedMaxLevel = 1; if (maxBackoff != 0 && multiplier != 0) { var x = config.MaxBackoffDuration.TotalSeconds / config.BackoffMultiplier.TotalSeconds; expectedMaxLevel = (int)Math.Ceiling(Math.Log(x, 2)) + 1; if (expectedMaxLevel <= 0) { expectedMaxLevel = 1; } } bool increaseBackoffLevel; if (expectedMaxLevel > 1) { increaseBackoffLevel = backoffStrategy.Calculate(config, expectedMaxLevel - 1).IncreaseBackoffLevel; Assert.IsTrue(increaseBackoffLevel, string.Format("increaseBackoff max={0} multiplier={1} level={2} expectedMaxLevel={3}", config.MaxBackoffDuration, config.BackoffMultiplier, expectedMaxLevel - 1, expectedMaxLevel)); } increaseBackoffLevel = backoffStrategy.Calculate(config, expectedMaxLevel).IncreaseBackoffLevel; Assert.IsFalse(increaseBackoffLevel, string.Format("increaseBackoff max={0} multiplier={1} level={2} expectedMaxLevel={3}", config.MaxBackoffDuration, config.BackoffMultiplier, expectedMaxLevel, expectedMaxLevel)); } } }
private Policy defaultPolicy(Operation operation) { return(Policy.HandleInner <ApiException>().OrInner <HttpRequestException>() .WaitAndRetryForever(retryAttempt => { backoffStrategy.Reconfigure(0); return TimeSpan.FromMilliseconds(backoffStrategy.Calculate()); }, (ex, span) => { Console.WriteLine($"Failure in operation {operation} topic {topicName} with error {ex.GetType().ToString()}. Will try again in {span} seconds..."); } )); }
public void DoPolling() { // Query External Tasks var fetchAndLockBackoff = 0L; try { var fetchExternalTasks = new FetchExternalTasks() { WorkerId = workerId, MaxTasks = topicManagerInfo.MaxTasks, Topics = new List <FetchExternalTaskTopic>() { new FetchExternalTaskTopic(topicManagerInfo.TopicName, topicManagerInfo.LockDurationInMilliseconds) { Variables = topicManagerInfo.VariablesToFetch == null ? topicManagerInfo.VariablesToFetch : null } } }; var tasks = new List <LockedExternalTask>(); policyManager.fetchAndLockPolicy().Execute(() => { tasks = externalTaskService.FetchAndLock(fetchExternalTasks).Result; }); backoffStrategy.Reconfigure(tasks.Count); fetchAndLockBackoff = backoffStrategy.Calculate(); Console.WriteLine($"Fetch and locked {tasks.Count} tasks in topic {topicManagerInfo.TopicName}. Will try again in {TimeSpan.FromMilliseconds(fetchAndLockBackoff)} seconds"); // run them in parallel with a max degree of parallelism Parallel.ForEach( tasks, new ParallelOptions { MaxDegreeOfParallelism = topicManagerInfo.MaxDegreeOfParallelism }, externalTask => { Execute(externalTask); } ); } finally { // schedule next run (if not stopped in between) if (taskQueryTimer != null) { taskQueryTimer.Change(TimeSpan.FromMilliseconds(fetchAndLockBackoff), TimeSpan.FromMilliseconds(Timeout.Infinite)); } } }