public void RetryPolicy_ExponentialEaseIn_ShouldBeCorrect()
        {
            // fail on all retries
            var startTime             = DateTime.Now;
            var timeBetweenRetries    = TimeSpan.FromMilliseconds(50);
            var maxTimeBetweenRetries = TimeSpan.FromMilliseconds(500);
            var maxRetries            = 10;
            var retryTimes            = new List <TimeSpan>();
            var retryPolicy           = RetryPolicyFactory.Create(RetryPolicy.EasedBackoff, new RetryPolicyOptions {
                EasingFunction = AnyRetry.Math.EasingFunction.ExponentialEaseOut, MaxRetryInterval = maxTimeBetweenRetries
            });

            for (var i = 0; i < maxRetries; i++)
            {
                retryTimes.Add(retryPolicy.ApplyPolicy(RetryParameters.Create(startTime, timeBetweenRetries, i, maxRetries)));
            }

            // elastic ease in
            var toleranceSeconds = 0.001;

            Assert.That(retryTimes.Skip(0).First().TotalSeconds, Is.EqualTo(0.05).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(1).First().TotalSeconds, Is.EqualTo(0.3185313).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(2).First().TotalSeconds, Is.EqualTo(0.4428445).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(3).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(4).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(5).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(6).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(7).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            // last timeout should be equal to max
            Assert.AreEqual(retryTimes.Skip(9).First(), TimeSpan.FromMilliseconds(500));
        }
Exemple #2
0
        public Guid AddJob <TJob>(Expression <Action <TJob> > jobExpression, RetryParameters retryParameters = null, DateTimeOffset?executionTime = null, string queueName = "default")
        {
            var jobInfo = JobCreator.Create <TJob>(jobExpression);
            var newJob  = new OddJobWithMetaAndStorageData()
            {
                JobId           = Guid.NewGuid(),
                JobArgs         = jobInfo.JobArgs,
                MethodName      = jobInfo.MethodName,
                RetryParameters = retryParameters,
                TypeExecutedOn  = jobInfo.TypeExecutedOn,
                CreatedOn       = DateTime.Now,
                Status          = JobStates.New
            };

            if (jobStore.ContainsKey(queueName) == false)
            {
                lock (dictionaryLock)
                {
                    jobStore.GetOrAdd(queueName, new List <OddJobWithMetaAndStorageData>());
                }
            }
            lock (jobLock)
            {
                jobStore[queueName].Add(newJob);
            }
            return(newJob.JobId);
        }
        /// <summary>
        /// Creates a Serialized Job Definition.
        /// Complex Parameters are stored as JSON strings,
        /// And Type Information is stored in a nonversioned format by default.
        /// </summary>
        /// <typeparam name="T">The type of the job to execute.</typeparam>
        /// <param name="jobExpression">The job Expression</param>
        /// <param name="retryParameters">The retry parameters to use, if any.</param>
        /// <param name="executionTime">A time to schedule; use this to schedule jobs in future</param>
        /// <param name="queueName">The Queue to resolve</param>
        /// <param name="typeNameSerializer">To change the default behavior (nonversioned types) specify a different <see cref="ITypeNameSerializer"/> here.</param>
        /// <returns>A wire-safe Serializable job definition.</returns>
        public static SerializableOddJob CreateJobDefinition <T>(Expression <Action <T> > jobExpression,
                                                                 RetryParameters retryParameters = null, DateTimeOffset?executionTime = null, string queueName = "default", ITypeNameSerializer typeNameSerializer = null)
        {
            var job   = JobCreator.Create(jobExpression);
            var mySer = typeNameSerializer ?? new UnversionedTypeSerializer();

            return(new SerializableOddJob()
            {
                JobId = job.JobId,
                MethodName = job.MethodName,
                JobArgs = job.JobArgs.Select((a, i) => new OddJobSerializedParameter()
                {
                    Ordinal = i,
                    Name = a.Name,
                    Value = Newtonsoft.Json.JsonConvert.SerializeObject(a.Value),
                    TypeName = mySer.GetTypeName(a.Value.GetType())
                }).ToArray(),
                TypeExecutedOn = mySer.GetTypeName(job.TypeExecutedOn),
                Status = job.Status,
                MethodGenericTypes = job.MethodGenericTypes.Select(q => mySer.GetTypeName(q)).ToArray(),
                RetryParameters = retryParameters ?? new RetryParameters(),
                ExecutionTime = executionTime,
                QueueName = queueName
            });
        }
        public void RetryPolicy_Exponential_ShouldBeCorrect()
        {
            // fail on all retries
            var startTime             = DateTime.Now;
            var timeBetweenRetries    = TimeSpan.FromMilliseconds(50);
            var maxTimeBetweenRetries = TimeSpan.FromMilliseconds(10000);
            var maxRetries            = 10;
            var retryTimes            = new List <TimeSpan>();
            var options = new RetryPolicyOptions {
                MaxRetryInterval = maxTimeBetweenRetries,
            };
            var retryPolicy = RetryPolicyFactory.Create(RetryPolicy.ExponentialBackoff, options);

            for (var i = 0; i < maxRetries; i++)
            {
                retryTimes.Add(retryPolicy.ApplyPolicy(RetryParameters.Create(startTime, timeBetweenRetries, i, maxRetries)));
            }

            // there is a 20% randomness to the delay
            var randomDelay = TimeSpan.FromMilliseconds(timeBetweenRetries.Milliseconds * 0.2);

            // first timeout should have nearly no delay
            Assert.LessOrEqual(timeBetweenRetries - randomDelay, retryTimes.First());
            // exponential increase
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 2 - (timeBetweenRetries.TotalMilliseconds * 2 * 0.2)), retryTimes.Skip(1).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 4 - (timeBetweenRetries.TotalMilliseconds * 4 * 0.2)), retryTimes.Skip(2).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 8 - (timeBetweenRetries.TotalMilliseconds * 8 * 0.2)), retryTimes.Skip(3).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 16 - (timeBetweenRetries.TotalMilliseconds * 16 * 0.2)), retryTimes.Skip(4).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 32 - (timeBetweenRetries.TotalMilliseconds * 32 * 0.2)), retryTimes.Skip(5).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 64 - (timeBetweenRetries.TotalMilliseconds * 64 * 0.2)), retryTimes.Skip(6).First());
            Assert.LessOrEqual(TimeSpan.FromMilliseconds(timeBetweenRetries.TotalMilliseconds * 128 - (timeBetweenRetries.TotalMilliseconds * 128 * 0.2)), retryTimes.Skip(7).First());
            Assert.AreEqual(TimeSpan.FromMilliseconds(10000), retryTimes.Skip(8).First());
            Assert.AreEqual(TimeSpan.FromMilliseconds(10000), retryTimes.Skip(9).First());
        }
Exemple #5
0
 public virtual Guid AddJob <TJob>(Expression <Action <TJob> > jobExpression, RetryParameters retryParameters = null,
                                   DateTimeOffset?executionTime = null, string queueName = "default")
 {
     using (var conn = _jobQueueConnectionFactory.CreateDataConnection(_mappingSchema.MappingSchema))
     {
         var ser = SerializableJobCreator.CreateJobDefinition(jobExpression, retryParameters, executionTime, queueName);
         AddJob(ser);
         return(ser.JobId);
     }
 }
Exemple #6
0
        /// <summary>
        /// Apply the policy
        /// </summary>
        /// <param name="retryParameters"></param>
        /// <returns></returns>
        public TimeSpan ApplyPolicy(RetryParameters retryParameters)
        {
            var retrySteps  = _options.MaxRetrySteps ?? retryParameters.RetryIteration;
            var retryCount  = _options.MaxRetrySteps ?? retryParameters.RetryCount;
            var maxInterval = _options.MaxRetryInterval;

            if (maxInterval == TimeSpan.MinValue)
            {
                maxInterval = TimeSpan.FromMilliseconds(retryParameters.RetryInterval.TotalMilliseconds * retrySteps);
            }
            var minInterval = retryParameters.RetryInterval;

            return(GetRetryTimeoutSeconds(retryParameters.RetryIteration, retryCount, minInterval, maxInterval, _options.EasingFunction));
        }
        public Guid AddJob <TJob>(Expression <Action <TJob> > jobExpression, RetryParameters retryParameters = null, DateTimeOffset?executionTime = null, string queueName = "default")
        {
            var jobData = JobCreator.Create(jobExpression);
            var toSer   = new FileSystemJobMetaData()
            {
                JobId              = Guid.NewGuid(),
                JobArgs            = jobData.JobArgs,
                MethodName         = jobData.MethodName,
                RetryParameters    = retryParameters ?? new RetryParameters(0, TimeSpan.FromSeconds(0), 0, null),
                TypeExecutedOn     = jobData.TypeExecutedOn,
                QueueName          = queueName,
                CreatedOn          = DateTime.Now,
                Status             = JobStates.New,
                MethodGenericTypes = jobData.MethodGenericTypes
            };

            WriteJobToQueue(toSer);
            return(toSer.JobId);
        }
        public void RetryPolicy_SineEaseIn_WithSteps_ShouldBeCorrect()
        {
            // fail on all retries
            const int maxRetrySteps         = 5;
            const int maxRetries            = 30;
            var       startTime             = DateTime.Now;
            var       timeBetweenRetries    = TimeSpan.FromMilliseconds(500);
            var       maxTimeBetweenRetries = TimeSpan.FromMilliseconds(2000);
            var       retryTimes            = new List <TimeSpan>();
            var       options = new RetryPolicyOptions
            {
                EasingFunction   = AnyRetry.Math.EasingFunction.SineEaseIn,
                MaxRetryInterval = maxTimeBetweenRetries,
                MaxRetrySteps    = maxRetrySteps
            };
            var retryPolicy = RetryPolicyFactory.Create(RetryPolicy.EasedBackoff, options);

            for (var i = 0; i < maxRetries; i++)
            {
                retryTimes.Add(retryPolicy.ApplyPolicy(RetryParameters.Create(startTime, timeBetweenRetries, i, maxRetries)));
            }

            // linear increase up to a max of maxRetrySteps then it should level off
            Assert.AreEqual(0.5, System.Math.Round(retryTimes.Skip(0).First().TotalSeconds, 2));
            Assert.AreEqual(0.6522409, retryTimes.Skip(1).First().TotalSeconds);
            Assert.AreEqual(1.0857864, retryTimes.Skip(2).First().TotalSeconds);
            Assert.AreEqual(1.7346331, retryTimes.Skip(3).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(4).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(5).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(6).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(7).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(8).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(10).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(11).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(12).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(13).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(14).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(15).First().TotalSeconds);
            Assert.AreEqual(2.0, retryTimes.Skip(16).First().TotalSeconds);
        }
        public void RetryPolicy_EasedLinear_WithSteps_ShouldBeCorrect()
        {
            // fail on all retries
            const int maxRetrySteps         = 5;
            const int maxRetries            = 10;
            var       startTime             = DateTime.Now;
            var       timeBetweenRetries    = TimeSpan.FromMilliseconds(500);
            var       maxTimeBetweenRetries = TimeSpan.FromMilliseconds(10000);
            var       retryTimes            = new List <TimeSpan>();
            var       options = new RetryPolicyOptions
            {
                EasingFunction   = AnyRetry.Math.EasingFunction.Linear,
                MaxRetryInterval = maxTimeBetweenRetries,
                MaxRetrySteps    = maxRetrySteps
            };
            var retryPolicy = RetryPolicyFactory.Create(RetryPolicy.EasedBackoff, options);

            for (var i = 0; i < maxRetries; i++)
            {
                retryTimes.Add(retryPolicy.ApplyPolicy(RetryParameters.Create(startTime, timeBetweenRetries, i, maxRetries)));
            }

            // linear increase up to a max of maxRetrySteps then it should level off
            var toleranceSeconds = 0.0;

            Assert.That(retryTimes.Skip(0).First().TotalSeconds, Is.EqualTo(0.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(1).First().TotalSeconds, Is.EqualTo(3.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(2).First().TotalSeconds, Is.EqualTo(5.5).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(3).First().TotalSeconds, Is.EqualTo(8.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(4).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(5).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(6).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(7).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(8).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
            Assert.That(retryTimes.Skip(9).First().TotalSeconds, Is.EqualTo(10.0).Within(toleranceSeconds));
        }
Exemple #10
0
 /// <summary>
 /// Apply the policy
 /// </summary>
 /// <param name="retryParameters"></param>
 /// <returns></returns>
 public TimeSpan ApplyPolicy(RetryParameters retryParameters)
 {
     return(retryParameters.RetryInterval);
 }
Exemple #11
0
 /// <summary>
 /// Apply the retry policy
 /// </summary>
 /// <param name="retryParameters"></param>
 /// <returns></returns>
 public TimeSpan ApplyPolicy(RetryParameters retryParameters)
 {
     return(SleepIntervalMs(retryParameters.RetryInterval, retryParameters.RetryIteration, _defaultMaxRelativeRandomSpreadPercent));
 }