예제 #1
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);
     }
 }
예제 #2
0
        /// <summary>The register exception.</summary>
        /// <param name="retryPolicy">The retry policy.</param>
        /// <param name="state">The state.</param>
        /// <param name="context">The context.</param>
        /// <param name="e">The e.</param>
        /// <exception cref="RetryException"></exception>
        protected void RegisterThrowable(IRetryPolicy retryPolicy, IRetryState state, IRetryContext context, Exception e)
        {
            if (state != null)
            {
                var key = state.GetKey();
                if (context.RetryCount > 0 && !this.retryContextCache.ContainsKey(key))
                {
                    throw new RetryException(
                              "Inconsistent state for failed item key: cache key has changed. "
                              + "Consider whether equals() or hashCode() for the key might be inconsistent, "
                              + "or if you need to supply a better key");
                }

                this.retryContextCache.Put(key, context);
            }

            retryPolicy.RegisterException(context, e);
        }
예제 #3
0
        /// <summary>Actions to take after final attempt has failed. If there is state clean
        /// up the cache. If there is a recovery callback, execute that and return
        /// its result. Otherwise throw an exception.</summary>
        /// <param name="recoveryCallback">The callback for recovery (might be null).</param>
        /// <param name="context">The current retry context.</param>
        /// <param name="state">The state.</param>
        /// <returns>The T.</returns>
        /// <typeparam name="T">Type T.</typeparam>
        protected T HandleRetryExhausted <T>(Func <IRetryContext, T> recoveryCallback, IRetryContext context, IRetryState state)
        {
            if (state != null)
            {
                this.retryContextCache.Remove(state.GetKey());
            }

            if (recoveryCallback != null)
            {
                return(recoveryCallback.Invoke(context));
            }

            if (state != null)
            {
                Logger.Debug(m => m("Retry exhausted after last attempt with no recovery path."));
                throw new ExhaustedRetryException("Retry exhausted after last attempt with no recovery path", context.LastException);
            }

            throw WrapIfNecessary(context.LastException);
        }
예제 #4
0
        /// <summary>Delegate to the <see cref="IRetryPolicy"/> having checked in the cache for an existing value if the state is not null.</summary>
        /// <param name="retryPolicy">The retry policy.</param>
        /// <param name="state">The state.</param>
        /// <returns>The Spring.Retry.Retry.IRetryContext, either a new one or the one used last time the same state was encountered.</returns>
        protected IRetryContext Open(IRetryPolicy retryPolicy, IRetryState state)
        {
            if (state == null)
            {
                return(this.DoOpenInternal(retryPolicy));
            }

            var key = state.GetKey();

            if (state.IsForceRefresh())
            {
                return(this.DoOpenInternal(retryPolicy));
            }

            // If there is no cache hit we can avoid the possible expense of the
            // cache re-hydration.
            if (!this.retryContextCache.ContainsKey(key))
            {
                // The cache is only used if there is a failure.
                return(this.DoOpenInternal(retryPolicy));
            }

            var context = this.retryContextCache.Get(key);

            if (context == null)
            {
                if (this.retryContextCache.ContainsKey(key))
                {
                    throw new RetryException(
                              "Inconsistent state for failed item: no history found. "
                              + "Consider whether equals() or hashCode() for the item might be inconsistent, "
                              + "or if you need to supply a better ItemKeyGenerator");
                }

                // The cache could have been expired in between calls to
                // containsKey(), so we have to live with this:
                return(this.DoOpenInternal(retryPolicy));
            }

            return(context);
        }