Class OutboxBackoff

java.lang.Object
org.keycloak.events.outbox.OutboxBackoff

public class OutboxBackoff extends Object
Computes the exponential-backoff next-attempt timestamp for a failed outbox delivery, and decides when a row has exhausted its budget and should be transitioned to DEAD_LETTER.

The backoff curve and the dead-letter threshold are configured per OutboxConfig.backoff(), so different consumers (SSF push, webhooks, ...) can pick curves that match their delivery semantics.

A small uniform jitter (±25% of the base delay) is mixed in on each computation so a flood of rows enqueued in the same tick don't all wake up to retry in the same millisecond — spreading the retry load in clustered deployments and across receivers.

  • Field Details

    • DEFAULT_MAX_ATTEMPTS

      public static final int DEFAULT_MAX_ATTEMPTS
      See Also:
    • DEFAULT_HTTP_PUSH_CURVE

      public static final List<Duration> DEFAULT_HTTP_PUSH_CURVE
      Default HTTP-push curve — sensible for receivers that respond to an HTTP POST. Consumers with different delivery semantics (e.g. internal queue write) should provide their own.
    • maxAttempts

      protected final int maxAttempts
    • curve

      protected final List<Duration> curve
  • Constructor Details

    • OutboxBackoff

      public OutboxBackoff()
    • OutboxBackoff

      public OutboxBackoff(int maxAttempts, List<Duration> curve)
  • Method Details

    • isExhausted

      public boolean isExhausted(int attempts)
      Returns true if the row has burned through its retry budget and should be transitioned to DEAD_LETTER instead of scheduling another attempt.
      Parameters:
      attempts - the value of attempts after the current failure has been accounted for.
    • computeNextAttemptAt

      public Instant computeNextAttemptAt(Instant now, int attempts)
      Computes the next_attempt_at timestamp for a row whose attempts counter has just been incremented to the given value after a failure. Callers should only invoke this when isExhausted(int) returns false.
    • getMaxNaturalRetryDuration

      public Duration getMaxNaturalRetryDuration()
      Sum of the curve up to maxAttempts entries — the worst-case time a row can spend in PENDING under the natural retry path before exhausting attempts. Operators tuning pendingMaxAge backstops should keep that value comfortably above this floor.
    • baseDelayFor

      protected Duration baseDelayFor(int attempts)
    • getCurve

      public List<Duration> getCurve()
    • getMaxAttempts

      public int getMaxAttempts()