/// <summary>
        /// Method for registering a context - should only be used by
        /// <see cref="IRetryOperations{T}"/> implementations to ensure that
        /// <see cref="GetContext"/> always returns the correct value.
        /// </summary>
        /// <param name="context">The new context to register.</param>
        /// <returns>The old context if there was one.</returns>
        public static IRetryContext Register(IRetryContext context)
        {
            var oldContext = GetContext();

            RetrySynchronizationManager.context.Value = context;
            return(oldContext);
        }
Ejemplo n.º 2
0
        public async Task Send(ConsumeContext <T> context, IPipe <ConsumeContext <T> > next)
        {
            try
            {
                await next.Send(context);
            }
            catch (Exception ex)
            {
                if (!_retryPolicy.CanRetry(ex))
                {
                    throw;
                }

                try
                {
                    MessageRedeliveryContext redeliveryContext;
                    if (!context.TryGetPayload(out redeliveryContext))
                    {
                        throw new ContextException("The message redelivery context was not available to delay the message", ex);
                    }

                    TimeSpan delay;
                    using (IRetryContext retryContext = _retryPolicy.GetRetryContext())
                    {
                        retryContext.CanRetry(ex, out delay);
                    }

                    await redeliveryContext.ScheduleRedelivery(delay);
                }
                catch (Exception redeliveryException)
                {
                    throw new ContextException("The message delivery could not be rescheduled", new AggregateException(redeliveryException, ex));
                }
            }
        }
        /// <summary>Delegate to the policies that were in operation when the context was
        /// created. If any of them cannot retry then return false, otherwise return true.<see cref="IRetryPolicy.CanRetry"/></summary>
        /// <param name="context">The context.</param>
        /// <returns>The System.Boolean.</returns>
        public bool CanRetry(IRetryContext context)
        {
            var contexts = ((CompositeRetryContext)context).contexts;
            var policies = ((CompositeRetryContext)context).policies;

            var retryable = true;

            if (this.optimistic)
            {
                retryable = false;
                for (var i = 0; i < contexts.Length; i++)
                {
                    if (policies[i].CanRetry(contexts[i]))
                    {
                        retryable = true;
                    }
                }
            }
            else
            {
                for (var i = 0; i < contexts.Length; i++)
                {
                    if (!policies[i].CanRetry(contexts[i]))
                    {
                        retryable = false;
                    }
                }
            }

            return(retryable);
        }
Ejemplo n.º 4
0
 private void DoCloseInterceptors <T>(Func <IRetryContext, T> callback, IRetryContext context, Exception lastException)
 {
     for (var i = this.listeners.Length; i-- > 0;)
     {
         this.listeners[i].Close(context, callback, lastException);
     }
 }
Ejemplo n.º 5
0
 private void DoOnErrorInterceptors <T>(Func <IRetryContext, T> callback, IRetryContext context, Exception throwable)
 {
     for (var i = this.listeners.Length; i-- > 0;)
     {
         this.listeners[i].OnError(context, callback, throwable);
     }
 }
        /// <summary>Delegate to the policies that were in operation when the context was
        /// created. If any of them fails to close the exception is propagated (and
        /// those later in the chain are closed before re-throwing).<see cref="IRetryPolicy.Close"/></summary>
        /// <param name="context">The context.</param>
        /// <exception cref="Exception"></exception>
        public void Close(IRetryContext context)
        {
            var       contexts  = ((CompositeRetryContext)context).contexts;
            var       policies  = ((CompositeRetryContext)context).policies;
            Exception exception = null;

            for (var i = 0; i < contexts.Length; i++)
            {
                try
                {
                    policies[i].Close(contexts[i]);
                }
                catch (Exception e)
                {
                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (exception != null)
            {
                throw exception;
            }
        }
        public static IRetryContext Register(IRetryContext context)
        {
            var oldContext = GetContext();

            _context.Value = context;
            return(oldContext);
        }
Ejemplo n.º 8
0
        public async Task PerformAsync(IRetryContext context, CancellationToken cancellationToken)
        {
            ThrowIf.Null(context, "context");
            await context.Request.PerformAsync(cancellationToken);

            context.Request.ProcessResult(context);
        }
 /// <summary>The register exception.</summary>
 /// <param name="context">The context.</param>
 /// <param name="exception">The exception.</param>
 public void RegisterException(IRetryContext context, Exception exception)
 {
     this.policy = this.exceptionClassifier.Classify(exception);
     AssertUtils.ArgumentNotNull(this.policy, "Could not locate policy for exception=[" + exception + "].");
     this.context = this.GetContext(this.policy, context.GetParent());
     this.policy.RegisterException(this.context, exception);
 }
Ejemplo n.º 10
0
        async Task Attempt(RetryConsumeContext context, IPipe <ConsumeContext> next)
        {
            context.ClearPendingFaults();

            TimeSpan delay;

            try
            {
                await next.Send(context).ConfigureAwait(false);

                return;
            }
            catch (Exception ex)
            {
                if (!_retryPolicy.CanRetry(ex))
                {
                    context.NotifyPendingFaults();
                    throw;
                }

                // by not adding the retry payload until the exception occurs, the deepest retry filter
                // is the one to set the actual retry context with the deepest configured policy
                IRetryContext retryContext = context.GetOrAddPayload(() => _retryPolicy.GetRetryContext());
                if (!retryContext.CanRetry(ex, out delay))
                {
                    context.NotifyPendingFaults();
                    throw;
                }
            }

            await Task.Delay(delay).ConfigureAwait(false);

            await Attempt(context, next).ConfigureAwait(false);
        }
        /// <summary>Delegate to the policies that were in operation when the context was
        /// created. If any of them cannot retry then return false, otherwise return true.<see cref="IRetryPolicy.CanRetry"/></summary>
        /// <param name="context">The context.</param>
        /// <returns>The System.Boolean.</returns>
        public bool CanRetry(IRetryContext context)
        {
            var contexts = ((CompositeRetryContext)context).contexts;
            var policies = ((CompositeRetryContext)context).policies;

            var retryable = true;

            if (this.optimistic)
            {
                retryable = false;
                for (var i = 0; i < contexts.Length; i++)
                {
                    if (policies[i].CanRetry(contexts[i]))
                    {
                        retryable = true;
                    }
                }
            }
            else
            {
                for (var i = 0; i < contexts.Length; i++)
                {
                    if (!policies[i].CanRetry(contexts[i]))
                    {
                        retryable = false;
                    }
                }
            }

            return retryable;
        }
        /// <summary>The register exception.</summary>
        /// <param name="context">The context.</param>
        /// <param name="exception">The exception.</param>
        public void RegisterException(IRetryContext context, Exception exception)
        {
            var policy = (IRetryPolicy)context;

            policy.RegisterException(context, exception);
            ((RetryContextSupport)context).RegisterException(exception);
        }
Ejemplo n.º 13
0
        static async Task <T> Attempt <T>(IRetryContext retryContext, Func <Task <T> > retryMethod, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                throw new TaskCanceledException();
            }

            TimeSpan delay;

            try
            {
                return(await retryMethod().ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                if (!retryContext.CanRetry(ex, out delay))
                {
                    throw;
                }
            }

            await Task.Delay(delay, cancellationToken).ConfigureAwait(false);

            return(await Attempt(retryContext, retryMethod, cancellationToken).ConfigureAwait(false));
        }
 public object Recover(IRetryContext context)
 {
     replyMessage.Value = SendRetryContextAccessor.GetMessage(context);
     replyAddress.Value = SendRetryContextAccessor.GetAddress(context);
     throwable.Value    = context.LastException;
     return(null);
 }
        public static IRetryContext Clear()
        {
            var           value  = GetContext();
            IRetryContext parent = value == null ? null : value.Parent;

            _context.Value = parent;
            return(value);
        }
 /// <summary>The close.</summary>
 /// <param name="context">The context.</param>
 public void Close(IRetryContext context)
 {
     // Only close those policies that have been used (opened):
     foreach (var policy in this.contexts.Keys)
     {
         policy.Close(this.GetContext(policy, context.GetParent()));
     }
 }
Ejemplo n.º 17
0
 public static async Task Retry(this IRetryPolicy retryPolicy, Func <Task> retryMethod,
                                CancellationToken cancellationToken = default(CancellationToken))
 {
     using (IRetryContext retryContext = retryPolicy.GetRetryContext())
     {
         await Attempt(retryContext, retryMethod, cancellationToken).ConfigureAwait(false);
     }
 }
Ejemplo n.º 18
0
        public async Task PerformAsync(IRetryContext context, CancellationToken cancellationToken)
        {
            ThrowIf.Null(context, "context");

            foreach (IStrategy strategy in this.strategies)
            {
                await strategy.PerformAsync(context, cancellationToken);
            }
        }
Ejemplo n.º 19
0
        public async Task PerformAsync(IRetryContext context, CancellationToken cancellationToken)
        {
            ThrowIf.Null(context, "context");

            if (this.condition(context))
            {
                await this.strategy.PerformAsync(context, cancellationToken);
            }
        }
Ejemplo n.º 20
0
                public bool Open(IRetryContext context)
                {
                    if (_adapter.RecoveryCallback != null)
                    {
                        _attributesHolder.Value = context;
                    }

                    return(true);
                }
Ejemplo n.º 21
0
            public object Recover(IRetryContext context)
            {
                if (!ShouldRequeue((MessagingException)context.LastException))
                {
                    return(_recoveryCallback.Recover(context));
                }

                throw (MessagingException)context.LastException;
            }
 public static async Task Retry <T>(this IRetryPolicy retryPolicy, ConsumeContext <T> context,
                                    Func <ConsumeContext <T>, Task> retryMethod)
     where T : class
 {
     using (IRetryContext retryContext = retryPolicy.GetRetryContext())
     {
         await Attempt(retryContext, context, retryMethod).ConfigureAwait(false);
     }
 }
        /// <summary>The recover.</summary>
        /// <param name="context">The context.</param>
        /// <returns>The System.Object.</returns>
        public object Recover(IRetryContext context)
        {
            if (this.recoverer != null)
            {
                return(this.recoverer.Recover <object>(this.args, context.LastException));
            }

            throw new ExhaustedRetryException("Retry was exhausted but there was no recovery path.");
        }
        /// <summary>The can retry.</summary>
        /// <param name="context">The context.</param>
        /// <returns>The System.Boolean.</returns>
        public bool CanRetry(IRetryContext context)
        {
            if (this.context == null)
            {
                // there was no error yet
                return(true);
            }

            return(this.policy.CanRetry(this.context));
        }
        /// <summary>Creates a new context that copies the existing policies and keeps a list of the contexts from each one. <see cref="IRetryPolicy.Open"/></summary>
        /// <param name="parent">The parent.</param>
        /// <returns>The Spring.Retry.Retry.IRetryContext.</returns>
        public IRetryContext Open(IRetryContext parent)
        {
            var list = new List <IRetryContext>();

            for (var i = 0; i < this.policies.Length; i++)
            {
                list.Add(this.policies[i].Open(parent));
            }

            return(new CompositeRetryContext(parent, list, this));
        }
Ejemplo n.º 26
0
        private bool DoOpenInterceptors <T>(Func <IRetryContext, T> callback, IRetryContext context)
        {
            var result = true;

            for (var i = 0; i < this.listeners.Length; i++)
            {
                result = result && this.listeners[i].Open(context, callback);
            }

            return(result);
        }
Ejemplo n.º 27
0
 /// <summary>Extension point for subclasses to decide on behaviour after catching an
 /// exception in a <see cref="IRetryCallback{T}"/>. Normal stateless behaviour is not
 /// to rethrow, and if there is state we rethrow.</summary>
 /// <param name="retryPolicy">The retry policy.</param>
 /// <param name="context">The context.</param>
 /// <param name="state">The state.</param>
 /// <returns>The System.Boolean.</returns>
 protected bool ShouldRethrow(IRetryPolicy retryPolicy, IRetryContext context, IRetryState state)
 {
     if (state == null)
     {
         return(false);
     }
     else
     {
         return(state.RollbackFor(context.LastException));
     }
 }
        /// <summary>Delegate to the policies that were in operation when the context was created. <see cref="IRetryPolicy.Close"/></summary>
        /// <param name="context">The context.</param>
        /// <param name="exception">The exception.</param>
        public void RegisterException(IRetryContext context, Exception exception)
        {
            var contexts = ((CompositeRetryContext)context).contexts;
            var policies = ((CompositeRetryContext)context).policies;

            for (var i = 0; i < contexts.Length; i++)
            {
                policies[i].RegisterException(contexts[i], exception);
            }

            ((RetryContextSupport)context).RegisterException(exception);
        }
        private IRetryContext GetContext(IRetryPolicy policy, IRetryContext parent)
        {
            IRetryContext context;

            this.contexts.TryGetValue(policy, out context);
            if (context == null)
            {
                context = policy.Open(parent);
                this.contexts.Add(policy, context);
            }

            return(context);
        }
Ejemplo n.º 30
0
        public async Task PerformAsync(IRetryContext context, CancellationToken cancellationToken)
        {
            TestabilityTrace.TraceSource.WriteNoise("DelayStrategy", "{0}: Sleeping '{1}' seconds.", context.ActivityId, this.delayTime.TotalSeconds);

            await AsyncWaiter.WaitAsync(this.delayTime, cancellationToken);

            TimeSpan nextSleepTime = this.getNextDelayTime(this.delayTime);

            if (nextSleepTime != this.delayTime)
            {
                TestabilityTrace.TraceSource.WriteNoise("DelayStrategy", "{0}: Increasing current delay time from '{1}' to '{2}' seconds.", context.ActivityId, this.delayTime.TotalSeconds, nextSleepTime.TotalSeconds);
                this.delayTime = nextSleepTime;
            }
        }
Ejemplo n.º 31
0
 /// <summary>Clean up the cache if necessary and close the context provided (if the flag indicates that processing was successful).</summary>
 /// <param name="retryPolicy">The retry policy.</param>
 /// <param name="context">The context.</param>
 /// <param name="state">The state.</param>
 /// <param name="succeeded">The succeeded.</param>
 protected void Close(IRetryPolicy retryPolicy, IRetryContext context, IRetryState state, bool succeeded)
 {
     if (state != null)
     {
         if (succeeded)
         {
             this.retryContextCache.Remove(state.GetKey());
             retryPolicy.Close(context);
         }
     }
     else
     {
         retryPolicy.Close(context);
     }
 }
Ejemplo n.º 32
0
        static async Task Attempt(IRetryContext retryContext, Func<Task> retryMethod,
            CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
                throw new TaskCanceledException();

            TimeSpan delay;
            try
            {
                await retryMethod().ConfigureAwait(false);

                return;
            }
            catch (Exception ex)
            {
                if (!retryContext.CanRetry(ex, out delay))
                    throw;
            }

            await Task.Delay(delay, cancellationToken).ConfigureAwait(false);

            await Attempt(retryContext, retryMethod, cancellationToken).ConfigureAwait(false);
        }
 /// <summary>Initializes a new instance of the <see cref="SimpleRetryContext"/> class.</summary>
 /// <param name="parent">The parent.</param>
 public SimpleRetryContext(IRetryContext parent)
     : base(parent)
 {
 }
 /// <summary>Get a status object that can be used to track the current operation
 /// according to this policy. Has to be aware of the latest exception and the
 /// number of attempts.</summary>
 /// <param name="parent">The parent.</param>
 /// <returns>The Spring.Retry.Retry.IRetryContext.</returns>
 public IRetryContext Open(IRetryContext parent)
 {
     return new SimpleRetryContext(parent);
 }
 /// <summary>Update the status with another attempted retry and the latest exception.</summary>
 /// <param name="context">The context.</param>
 /// <param name="exception">The throwable.</param>
 public void RegisterException(IRetryContext context, Exception exception)
 {
     var simpleContext = (SimpleRetryContext)context;
     simpleContext.RegisterException(exception);
 }
        /// <summary>Delegate to the policies that were in operation when the context was
        /// created. If any of them fails to close the exception is propagated (and
        /// those later in the chain are closed before re-throwing).<see cref="IRetryPolicy.Close"/></summary>
        /// <param name="context">The context.</param>
        /// <exception cref="Exception"></exception>
        public void Close(IRetryContext context)
        {
            var contexts = ((CompositeRetryContext)context).contexts;
            var policies = ((CompositeRetryContext)context).policies;
            Exception exception = null;
            for (var i = 0; i < contexts.Length; i++)
            {
                try
                {
                    policies[i].Close(contexts[i]);
                }
                catch (Exception e)
                {
                    if (exception == null)
                    {
                        exception = e;
                    }
                }
            }

            if (exception != null)
            {
                throw exception;
            }
        }
        /// <summary>The register exception.</summary>
        /// <param name="context">The context.</param>
        /// <param name="exception">The exception.</param>
        public void RegisterException(IRetryContext context, Exception exception)
        {
            ((RetryContextSupport)context).RegisterException(exception);

            // otherwise no-op - we only time out, otherwise retry everything...
        }
 /// <summary>
 /// Method for registering a context - should only be used by
 /// <see cref="IRetryOperations{T}"/> implementations to ensure that
 /// <see cref="GetContext"/> always returns the correct value.
 /// </summary>
 /// <param name="context">The new context to register.</param>
 /// <returns>The old context if there was one.</returns>
 public static IRetryContext Register(IRetryContext context)
 {
     var oldContext = GetContext();
     RetrySynchronizationManager.context.Value = context;
     return oldContext;
 }
 /// <summary>Returns false after the first exception. So there is always one try, and then the retry is prevented. <see cref="IRetryContext"/></summary>
 /// <param name="context">The context.</param>
 /// <returns>The System.Boolean.</returns>
 public virtual bool CanRetry(IRetryContext context)
 {
     return !((NeverRetryContext)context).IsFinished;
 }
 /// <summary>Returns null. Subclasses can add behaviour, e.g. * initial sleep before first attempt.</summary>
 /// <param name="context">The context.</param>
 /// <returns>The Spring.Retry.Retry.Backoff.IBackOffContext.</returns>
 public virtual IBackOffContext Start(IRetryContext context)
 {
     return null;
 }
 /// <summary>The put.</summary>
 /// <param name="key">The key.</param>
 /// <param name="context">The context.</param>
 /// <exception cref="NotImplementedException"></exception>
 public void Put(object key, IRetryContext context)
 {
     throw new NotImplementedException();
 }
 /// <summary>Initializes a new instance of the <see cref="NeverRetryContext"/> class.</summary>
 /// <param name="parent">The parent.</param>
 public NeverRetryContext(IRetryContext parent)
     : base(parent)
 {
 }
        /// <summary>Creates a new context that copies the existing policies and keeps a list of the contexts from each one. <see cref="IRetryPolicy.Open"/></summary>
        /// <param name="parent">The parent.</param>
        /// <returns>The Spring.Retry.Retry.IRetryContext.</returns>
        public IRetryContext Open(IRetryContext parent)
        {
            var list = new List<IRetryContext>();
            for (var i = 0; i < this.policies.Length; i++)
            {
                list.Add(this.policies[i].Open(parent));
            }

            return new CompositeRetryContext(parent, list, this);
        }
        /// <summary>Make the exception available for downstream use through the context. <see cref="IRetryPolicy.RegisterException"/></summary>
        /// <param name="context">The context.</param>
        /// <param name="exception">The exception.</param>
        public virtual void RegisterException(IRetryContext context, Exception exception)
        {
            ((NeverRetryContext)context).SetFinished();

            ((RetryContextSupport)context).RegisterException(exception);
        }
 /// <summary>Return a context that can respond to early termination requests, but does nothing else. <see cref="IRetryPolicy.Open"/></summary>
 /// <param name="parent">The parent.</param>
 /// <returns>The Spring.Retry.Retry.IRetryContext.</returns>
 public virtual IRetryContext Open(IRetryContext parent)
 {
     return new NeverRetryContext(parent);
 }
 /// <summary>Do nothing. <see cref="IRetryContext"/></summary>
 /// <param name="context">The context.</param>
 public virtual void Close(IRetryContext context)
 {
     // no-op
 }
 /// <summary>Test for retryable operation based on the status.</summary>
 /// <param name="context">The context.</param>
 /// <returns>True if the last exception was retryable and the number of attempts so far is less than the limit.</returns>
 public bool CanRetry(IRetryContext context)
 {
     var t = context.LastException;
     return (t == null || this.RetryForException(t)) && context.RetryCount < this.maxAttempts;
 }
Ejemplo n.º 48
0
 public NoRetryPolicy()
 {
     _retryContext = new NoRetryContext();
 }
 /// <summary>The close.</summary>
 /// <param name="context">The context.</param>
 public void Close(IRetryContext context)
 {
 }
 /// <summary>The open.</summary>
 /// <param name="parent">The parent.</param>
 /// <returns>The Spring.Retry.Retry.IRetryContext.</returns>
 public IRetryContext Open(IRetryContext parent)
 {
     return new TimeoutRetryContext(parent, this.timeout);
 }
Ejemplo n.º 51
0
 public CancelRetryContext(IRetryContext retryContext, CancellationToken cancellationToken)
 {
     _retryContext = retryContext;
     _cancellationToken = cancellationToken;
 }
 /// <summary>Initializes a new instance of the <see cref="TimeoutRetryContext"/> class.</summary>
 /// <param name="parent">The parent.</param>
 /// <param name="timeout">The timeout.</param>
 public TimeoutRetryContext(IRetryContext parent, long timeout)
     : base(parent)
 {
     this.start = DateTime.UtcNow;
     this.timeout = timeout;
 }
 /// <summary>Always return true. <see cref="IRetryPolicy.CanRetry"/></summary>
 /// <param name="context">The context.</param>
 /// <returns>The System.Boolean.</returns>
 public override bool CanRetry(IRetryContext context)
 {
     return true;
 }
 /// <summary>Initializes a new instance of the <see cref="RetryContextSupport"/> class.</summary>
 /// <param name="parent">The parent.</param>
 public RetryContextSupport(IRetryContext parent)
 {
     this.parent = parent;
 }
 /// <summary>Returns a new instance of <see cref="IBackOffContext"/>, seeded with this policy's settings.</summary>
 /// <param name="context">The context.</param>
 /// <returns>The Spring.Retry.Retry.Backoff.IBackOffContext.</returns>
 public override IBackOffContext Start(IRetryContext context)
 {
     return new ExponentialRandomBackOffContext(this.InitialInterval, this.Multiplier, this.MaxInterval);
 }
 /// <summary>Initializes a new instance of the <see cref="CompositeRetryContext"/> class.</summary>
 /// <param name="parent">The parent.</param>
 /// <param name="contexts">The contexts.</param>
 /// <param name="outer">The outer.</param>
 public CompositeRetryContext(IRetryContext parent, List<IRetryContext> contexts, CompositeRetryPolicy outer)
     : base(parent)
 {
     this.contexts = contexts.ToArray();
     this.policies = this.outer.policies;
     this.outer = outer;
 }
 /// <summary>Returns a new instance of <see cref="IBackOffContext"/> configured with the 'expSeed' and 'increment' values.</summary>
 /// <param name="context">The context.</param>
 /// <returns>The Spring.Retry.Retry.Backoff.IBackOffContext.</returns>
 public virtual IBackOffContext Start(IRetryContext context)
 {
     return new ExponentialBackOffContext(this.initialInterval, this.multiplier, this.maxInterval);
 }
        /// <summary>The put.</summary>
        /// <param name="key">The key.</param>
        /// <param name="context">The context.</param>
        /// <exception cref="RetryCacheCapacityExceededException"></exception>
        public void Put(object key, IRetryContext context)
        {
            if (this.map.Count >= this.capacity)
            {
                throw new RetryCacheCapacityExceededException(
                    "Retry cache capacity limit breached. "
                    + "Do you need to re-consider the implementation of the key generator, "
                    + "or the equals and hashCode of the items that failed?");
            }

            if (this.map.ContainsKey(key))
            {
                this.map[key] = context;
            }
            else
            {
                this.map.Add(key, context);
            }
        }
        /// <summary>Delegate to the policies that were in operation when the context was created. <see cref="IRetryPolicy.Close"/></summary>
        /// <param name="context">The context.</param>
        /// <param name="exception">The exception.</param>
        public void RegisterException(IRetryContext context, Exception exception)
        {
            var contexts = ((CompositeRetryContext)context).contexts;
            var policies = ((CompositeRetryContext)context).policies;
            for (var i = 0; i < contexts.Length; i++)
            {
                policies[i].RegisterException(contexts[i], exception);
            }

            ((RetryContextSupport)context).RegisterException(exception);
        }
 /// <summary>Only permits a retry if the timeout has not expired. Does not check the exception at all.</summary>
 /// <param name="context">The context.</param>
 /// <returns>The System.Boolean.</returns>
 public bool CanRetry(IRetryContext context)
 {
     return ((TimeoutRetryContext)context).IsAlive();
 }