コード例 #1
0
  /**
   * Delegate to the {@link RetryPolicy} having checked in the cache for an existing value if the
   * state is not null.
   *
   * @param state a {@link RetryState}
   * @param retryPolicy a {@link RetryPolicy} to delegate the context creation
   * @return a retry context, either a new one or the one used last time the same state was
   *     encountered
   */
  protected RetryContext open(RetryPolicy retryPolicy, RetryState state) {

    if (state == null) {
      return doOpenInternal(retryPolicy);
    }

    Object key = state.getKey();
    if (state.isForceRefresh()) {
      return doOpenInternal(retryPolicy, state);
    }

    // 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 doOpenInternal(retryPolicy, state);
    }

    RetryContext 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 doOpenInternal(retryPolicy, state);
    }

    // Start with a clean slate for state that others may be inspecting
    context.removeAttribute(RetryContext.CLOSED);
    context.removeAttribute(RetryContext.EXHAUSTED);
    context.removeAttribute(RetryContext.RECOVERED);
    return context;
  }