java.lang.Object
io.github.teceli.resiliencia.patterns.ratelimiter.RateLimiter<T>
All Implemented Interfaces:
Resilient<T>

public final class RateLimiter<T> extends Object implements Resilient<T>
RateLimiter pattern: bound how many calls may start per time window (fixed window, limit calls per period). Windows are aligned to the instant the limiter was created and advance in whole periods, as measured by the Clock. Callers over the limit either fail fast with RateLimiterException (default, maxWait zero) or wait via Clock.sleep(long) for up to maxWait until the next window opens; blocking a virtual thread is cheap. Holds live state (the current window and its used permits). Immutable in configuration and thread-safe by design — share one instance across all callers that must compete for the same budget. Each withX method returns a new, independent RateLimiter with a fresh window.
  • Method Details

    • of

      public static <T> RateLimiter<T> of(String name, int limit, Duration period)
      A RateLimiter allowing limit calls per period, rejecting excess calls immediately (maxWait zero). Refine via withX methods, e.g. withMaxWait(java.time.Duration) to let excess calls wait for the next window instead.
    • withLimit

      public RateLimiter<T> withLimit(int limit)
      Maximum number of calls allowed per period. Must be at least 1.
    • withPeriod

      public RateLimiter<T> withPeriod(Duration period)
      Length of the fixed window over which limit calls are allowed. Must be positive.
    • withMaxWait

      public RateLimiter<T> withMaxWait(Duration maxWait)
      How long an excess call may wait for the next window before being rejected. Zero (the default) rejects immediately.
    • withListener

      public RateLimiter<T> withListener(ResilienceEvent.Listener listener)
      Add a listener notified of every RateLimiterEvent emitted by this instance. Listener exceptions are logged and otherwise ignored — a broken listener never affects the outcome.
    • withClock

      public RateLimiter<T> withClock(Clock clock)
      Use a custom Clock instead of the system clock, e.g. a manual/virtual clock in tests to make window and wait assertions deterministic and instant.
    • name

      public String name()
      The name identifying this rate limiter instance, used in events and rejection exceptions.
    • limit

      public int limit()
      The configured maximum number of calls per period.
    • period

      public Duration period()
      The configured length of the fixed window.
    • maxWait

      public Duration maxWait()
      How long an excess call may wait for the next window before being rejected.
    • patternName

      public String patternName()
      Description copied from interface: Resilient
      The name of this pattern, e.g. "retry", "timeout", "circuit-breaker". Used for identification (e.g. by Policy) without coupling to concrete pattern types. Defaults to "custom" for user-defined Resilient implementations.
      Specified by:
      patternName in interface Resilient<T>
    • patternKind

      public PatternKind patternKind()
      Description copied from interface: Resilient
      The kind of this pattern, used for internal comparisons (e.g. Policy order validation). Unlike Resilient.patternName(), which is a free-form observability label, this is a closed enum the library can reason about exhaustively. Defaults to PatternKind.CUSTOM for user-defined Resilient implementations.
      Specified by:
      patternKind in interface Resilient<T>
    • call

      public T call(Resilient.Operation<T> operation) throws ResilientException
      Description copied from interface: Resilient
      Execute an operation with resilience guarantees. May throw ResilienciaException or a specific pattern exception.
      Specified by:
      call in interface Resilient<T>
      Throws:
      ResilientException
    • outcome

      public Outcome<T> outcome(Resilient.Operation<T> operation)
      Description copied from interface: Resilient
      Execute an operation and capture the result or failure as an Outcome. Never throws for a recorded Exception — always returns Success, Failure, or a pattern-specific outcome. An Error thrown by the operation propagates uncaught instead of being captured as a Failure: fatal JVM conditions (e.g. OutOfMemoryError) should not be treated as a recoverable result.
      Specified by:
      outcome in interface Resilient<T>