java.lang.Object
io.github.teceli.resiliencia.compose.Policy<T>
All Implemented Interfaces:
Resilient<T>

public final class Policy<T> extends Object implements Resilient<T>
Fluent composition of multiple resilience patterns. The first pattern passed to compose(io.github.teceli.resiliencia.core.api.Resilient<T>) is the outermost layer, invoked first. Each pattern added via and(io.github.teceli.resiliencia.core.api.Resilient<T>) becomes the new innermost layer, closer to the operation than every pattern added before it. Example: Policy.compose(retry).call(op) executes op with retry protection. Example: Policy.compose(circuitBreaker).and(retry).call(op) checks the circuit breaker first; retry sits inside it, closest to the operation.
  • Method Details

    • compose

      public static <T> Policy<T> compose(Resilient<T> pattern)
      Create a policy with a single pattern. This pattern becomes the outermost layer.
    • and

      public Policy<T> and(Resilient<T> pattern)
      Add another pattern to this policy. The new pattern becomes the innermost layer, closest to the operation; patterns added earlier stay further out. The new pattern is checked against every pattern already in the chain (transitively, not just the adjacent one) for known-bad orderings: Retry wrapping CircuitBreaker is rejected with InvalidPolicyException; Timeout wrapping Retry logs a WARN but proceeds, also emitting a PolicyValidationWarning to any listener already attached via withListener(ResilienceEvent.Listener).
      Throws:
      InvalidPolicyException - if the resulting ordering is known to be broken at runtime
    • withListener

      public Policy<T> withListener(ResilienceEvent.Listener listener)
      Add a listener notified of every PolicyValidationWarning emitted by this instance. Only observes warnings raised by and(Resilient) calls made after this listener was attached — useOptimumOrder(Resilient[]) builds its entire chain in one call with no opportunity to attach a listener mid-build, so any warning it triggers is only visible via the SLF4J log, which always fires regardless. Listener exceptions are logged and otherwise ignored — a broken listener never affects the outcome.
    • useOptimumOrder

      @SafeVarargs public static <T> Policy<T> useOptimumOrder(Resilient<T>... patterns)
      Create a policy from the given patterns, composed in the library's optimum order regardless of the order they are passed in — outermost to innermost: RateLimiter, CircuitBreaker, Bulkhead, Retry, Timeout. The result is a plain Policy, identical to what the equivalent compose(...).and(...) chain produces, and goes through the same ordering guardrail. The sort is stable: patterns of the same kind keep the relative order they were passed in.
    • hasOwnDeadline

      public boolean hasOwnDeadline()
      True if any pattern in this chain has its own deadline, checked recursively through nested Policy patterns. Without this override, a Retry configured with withOverallDeadline(...) but nested inside a sub-Policy would report false here (the Resilient default), silently defeating the Timeout-wraps-Retry WARN suppression that the same Retry would get in a flat chain.
      Specified by:
      hasOwnDeadline in interface Resilient<T>
    • call

      public T call(Resilient.Operation<T> operation) throws ResilientException
      Execute the operation through the pattern chain on the calling thread, blocking until complete. Returns the result, or throws whichever exception the innermost failing pattern throws. Policy propagates RuntimeExceptions (including all ResilientException subtypes) as-is, without wrapping. For Throwable types that are not RuntimeException (e.g., Error), wraps in ResilientException as a safety net.
      Specified by:
      call in interface Resilient<T>
      Throws:
      ResilientException - if the operation fails after passing through the pattern chain
    • outcome

      public Outcome<T> outcome(Resilient.Operation<T> operation)
      Execute and capture outcome (never throws). Chains all patterns so each wraps the operation before execution.
      Specified by:
      outcome in interface Resilient<T>