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

public final class Bulkhead<T> extends Object implements Resilient<T>
Bulkhead pattern: bound how many calls may execute concurrently, isolating the protected resource from overload. Built on a Semaphore — callers over the limit either fail fast with BulkheadFullException (default, maxWait zero) or block for up to maxWait until a permit frees up; blocking a virtual thread is cheap. Holds live state (the permits). Immutable in configuration and thread-safe by design — share one instance across all callers that must compete for the same permits. Each withX method returns a new, independent Bulkhead with a fresh, unused set of permits.
  • Method Details

    • of

      public static <T> Bulkhead<T> of(String name, int maxConcurrentCalls)
      A Bulkhead allowing the given number of concurrent calls, rejecting excess calls immediately (maxWait zero). Refine via withX methods, e.g. withMaxWait(java.time.Duration) to let excess calls wait for a permit instead.
    • withMaxConcurrentCalls

      public Bulkhead<T> withMaxConcurrentCalls(int maxConcurrentCalls)
      Maximum number of calls allowed to execute concurrently. Must be at least 1.
    • withMaxWait

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

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

      public Bulkhead<T> withClock(Clock clock)
      Use a custom Clock instead of the system clock for event timestamps. The permit wait is enforced against real elapsed time.
    • name

      public String name()
      The name identifying this bulkhead instance, used in events and rejection exceptions.
    • maxConcurrentCalls

      public int maxConcurrentCalls()
      The configured maximum number of concurrent calls.
    • maxWait

      public Duration maxWait()
      How long an excess call may wait for a permit 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>