Annotation Interface Idempotent


@Retention(RUNTIME) @Target({TYPE,METHOD}) public @interface Idempotent
Marks a Tool (or action method) as side-effecting and therefore requiring idempotency protection on retry (issue #91).

Without this annotation, @Resilience(retry = ...) on a side-effecting tool will happily call it 2× / 3× on transient failure — sending 3 emails, creating 3 GitHub issues, charging the card 3 times. Annotating the tool tells the framework to:

  1. Derive a stable key from the call (per strategy()).
  2. Check the IdempotencyStore before invocation.
  3. On hit, behave per onCacheHit().
  4. On miss, run the tool, cache the result for ttlSeconds().
  5. Propagate the key to upstream services that honor it (HTTP Idempotency-Key header on WEB_SERVICE actions).

Example


 @Idempotent(strategy = KeyStrategy.HASH_INPUT, ttlSeconds = 86400)
 public class SendEmailTool implements Tool {
     @Override
     public String execute(String query) { ... }
 }
 

For tools whose natural key is a single input field rather than a hash of everything, set strategy = EXPLICIT and override Tool.idempotencyKeyFor(input).

Since:
0.5.0 (issue #91)
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    boolean
    Whether to cache failures as well as successes.
    What to do when a retry hits the cache.
    How to derive the key.
    long
    How long the cached result is honored, in seconds.
  • Element Details

    • strategy

      KeyStrategy strategy
      How to derive the key. Default is KeyStrategy.HASH_INPUT.
      Default:
      HASH_INPUT
    • ttlSeconds

      long ttlSeconds
      How long the cached result is honored, in seconds. Default 1 hour. Set higher for slow-changing operations (a "create issue" call's deduplication window can sensibly be 24h+); lower for things where stale cached results would be misleading.
      Default:
      3600L
    • onCacheHit

      RetryBehavior onCacheHit
      What to do when a retry hits the cache. Default RetryBehavior.RETURN_CACHED.
      Default:
      RETURN_CACHED
    • cacheFailures

      boolean cacheFailures
      Whether to cache failures as well as successes. When true, a retry of a failed call is short-circuited (per onCacheHit()); when false (default), failures fall through and the tool may re-attempt. Cache-failures-on for deterministic-failure operations where re-attempt is wasteful; leave off for transient-failure operations where the caller does want a retry.
      Default:
      false