Class PreemptionSimulator

java.lang.Object
org.mockserver.mock.action.http.PreemptionSimulator

public class PreemptionSimulator extends Object
Process-wide state machine for a simulated server preemption (node drain / Spot reclamation / pre-SIGTERM): when start(PreemptionRequest) is called the server becomes cordoned — new data-plane exchanges are turned away (503 + Connection: close on HTTP/1.1, GOAWAY on HTTP/2, per PreemptionRequest.Mode) while in-flight requests are allowed to drain for a bounded window. It is a simulation only: it never calls stop() / stopAsync() and never tears down the event loops. The cordon clears on an explicit uncordon() or automatically after ttlMillis (a dead-man's switch so a forgotten simulation self-heals).

The design mirrors ServiceChaosRegistry's singleton + controllable-clock + TTL pattern, but is server-scoped (a single cordon, no host keying). It holds no Netty references: the in-flight count is read through an injected IntSupplier (wired from LifeCycle.getRequestsInFlight()), keeping mockserver-core free of a netty dependency. GOAWAY emission is performed lazily on the netty side when an HTTP/2 client hits a cordoned connection (see HttpRequestHandler); this class is the authoritative cordon state.

State is cleared on server reset (see HttpState.reset()).

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    true once the drain window has elapsed while still cordoned (stragglers may remain).
    long
    Milliseconds remaining in the drain window (until drainDeadlineMillis), floored at 0.
    boolean
    true when the active simulation signals HTTP/2 clients to drain via a GOAWAY frame (modes goaway and both).
     
    The active mode, or null when not cordoned.
    The active preemption request (effective, post-clamp), or null when not cordoned.
    long
    The lastStreamId to advertise on a preemption GOAWAY, or -1 when not cordoned or unset (-1 tells Http2GoAwayEmitter to use the connection's current last stream).
    int
    The current in-flight data-plane request count, via the wired supplier.
    boolean
    Whether the server is currently cordoned.
    boolean
    true when the active simulation rejects new data-plane exchanges with a 503 (modes reject503 and both).
    void
    Reset all state.
    void
    setInFlightSupplier(IntSupplier inFlightSupplier)
    Wire the supplier used to read the current in-flight data-plane request count (from LifeCycle.getRequestsInFlight()).
    Begin (or replace) a preemption simulation.
    A human-readable state string for the status endpoint: "inactive" when not cordoned, "draining" while within the drain window, or "drained" once the drain deadline has passed (the server stays cordoned until TTL/uncordon).
    void
    Clear the cordon explicitly (idempotent).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • PreemptionSimulator

      public PreemptionSimulator(LongSupplier clock)
  • Method Details

    • getInstance

      public static PreemptionSimulator getInstance()
    • setInFlightSupplier

      public void setInFlightSupplier(IntSupplier inFlightSupplier)
      Wire the supplier used to read the current in-flight data-plane request count (from LifeCycle.getRequestsInFlight()). Null is ignored.
    • start

      Begin (or replace) a preemption simulation. The drainMillis and ttlMillis are each clamped to preemptionSimulationMaxDrainMillis. When drainMillis is null it defaults to stopDrainMillis (the same drain budget a real graceful shutdown uses). When mode is null it defaults to PreemptionRequest.Mode.both.
      Returns:
      the effective request actually applied (with defaults and clamping resolved)
    • isCordoned

      public boolean isCordoned()
      Whether the server is currently cordoned. Auto-uncordons (lazily, here) once the TTL has elapsed, so a forgotten simulation self-heals without an explicit uncordon.
    • inFlight

      public int inFlight()
      The current in-flight data-plane request count, via the wired supplier.
    • getRequest

      public PreemptionRequest getRequest()
      The active preemption request (effective, post-clamp), or null when not cordoned.
    • getMode

      public PreemptionRequest.Mode getMode()
      The active mode, or null when not cordoned.
    • rejectsNewExchanges

      public boolean rejectsNewExchanges()
      true when the active simulation rejects new data-plane exchanges with a 503 (modes reject503 and both). When the mode is goaway only, new exchanges are not rejected with a 503 — the HTTP/2 GOAWAY alone signals clients to drain — so this returns false. Returns false when not cordoned.
    • emitsGoAway

      public boolean emitsGoAway()
      true when the active simulation signals HTTP/2 clients to drain via a GOAWAY frame (modes goaway and both). Returns false when not cordoned. Read by the netty runtime to decide whether to emit a lazy GOAWAY on a cordoned HTTP/2 connection. Thread-safe: reads the active request through the same path as isCordoned().
    • goAwayLastStreamId

      public long goAwayLastStreamId()
      The lastStreamId to advertise on a preemption GOAWAY, or -1 when not cordoned or unset (-1 tells Http2GoAwayEmitter to use the connection's current last stream).
    • drainRemainingMillis

      public long drainRemainingMillis()
      Milliseconds remaining in the drain window (until drainDeadlineMillis), floored at 0. Returns 0 when not cordoned. This reflects the drain budget, not the TTL.
    • drainDeadlinePassed

      public boolean drainDeadlinePassed()
      true once the drain window has elapsed while still cordoned (stragglers may remain).
    • state

      public String state()
      A human-readable state string for the status endpoint: "inactive" when not cordoned, "draining" while within the drain window, or "drained" once the drain deadline has passed (the server stays cordoned until TTL/uncordon).
    • uncordon

      public void uncordon()
      Clear the cordon explicitly (idempotent).
    • reset

      public void reset()
      Reset all state. Called on server reset and for test isolation. Does not clear the wired supplier.