private TimeSpan GetDelay(int attemptIndex, TimeSpan intervalDelay, RetryIntervalStrategy strategy, int scaleFactor)
        {
            if (attemptIndex < 1)
            {
                throw new IndexOutOfRangeException("Attempt index should not be < 1");
            }

            double factor = 1.0;

            switch (strategy)
            {
            case RetryIntervalStrategy.ConstantDelay:
                return(intervalDelay);

            case RetryIntervalStrategy.LinearDelay:
                factor = (attemptIndex - 1) * scaleFactor > 1 ? (attemptIndex - 1) * scaleFactor : 1;
                return(TimeSpan.FromMilliseconds(factor + intervalDelay.TotalMilliseconds));

            case RetryIntervalStrategy.ProgressiveDelay:
                factor = (attemptIndex - 1) * scaleFactor > 1 ? (attemptIndex - 1) * scaleFactor : 1;
                return(TimeSpan.FromMilliseconds(factor * intervalDelay.TotalMilliseconds));

            case RetryIntervalStrategy.ExponentialDelay:
                factor = Math.Pow(attemptIndex - 1, scaleFactor);
                factor = factor > 1 ? factor : 1;
                return(TimeSpan.FromMilliseconds(factor * intervalDelay.TotalMilliseconds));

            default:
                break;
            }

            throw new ArgumentException("strategy should be defined");
        }
 public RetryLogicState <TReturn> WithConstantInterval(TimeSpan interval)
 {
     this.CheckIsNotFrozen();
     this.intervalDelay    = interval;
     this.intervalStrategy = RetryIntervalStrategy.ConstantDelay;
     return(this);
 }
 public RetryLogicState <TReturn> WithExponentialInterval(TimeSpan interval, int scaleFactor)
 {
     this.CheckIsNotFrozen();
     this.intervalDelay    = interval;
     this.intervalStrategy = RetryIntervalStrategy.ExponentialDelay;
     this.scaleFactor      = scaleFactor;
     return(this);
 }
        private RetryLogicState()
        {
            // set default values
            this.numberOfAttempts  = 3;
            this.intervalDelay     = TimeSpan.FromMilliseconds(2000);
            this.intervalStrategy  = RetryIntervalStrategy.LinearDelay;
            this.scaleFactor       = 10;
            this.traceRetryEvents  = false;
            this.onFailureContinue = false;

            this.exceptions           = new List <Type>();
            this.onExceptionCallbacks = new Dictionary <Type, Action <Exception> >();
            this.onFailureCallbacks   = new List <Action>();
            this.onSuccessCallbacks   = new List <Action <TReturn> >();
        }