Class ForwardCircuitBreaker
host:port. After forwardProxyCircuitBreakerFailureThreshold consecutive failures
to one upstream the breaker trips open and #allowRequest(String) fails subsequent
requests fast (the caller returns a 503) for forwardProxyCircuitBreakerWindowMillis. Once
the window elapses the breaker moves to half-open: it permits a single trial request. A
success (#recordSuccess(String)) closes the breaker; a failure
(#recordFailure(String)) re-opens it for another window.
The whole mechanism is inert unless forwardProxyCircuitBreakerEnabled is true, so the
default behaviour (every request attempted) is unchanged.
The singleton instance is shared process-wide, consistent with
ChaosAutoHaltMonitor and LlmCostBudgetMonitor. The number of currently-open
upstreams is exposed via openCircuitCount() (and the mock_server_upstream_circuit_open
Prometheus gauge).
-
Method Summary
Modifier and TypeMethodDescriptionbooleanallowRequest(Configuration configuration, String key) Decide whether a request to the given upstream may proceed.static ForwardCircuitBreakerbooleanTrue when the breaker for the given key is currently open (open timestamp set).static StringkeyFor(InetSocketAddress remoteAddress) Build the stable per-upstream key from a resolved socket address (host and port only — never the path), returningnullwhen no usable host is available.intNumber of upstreams whose breaker is currently open (in the open or half-open state).voidrecordFailure(Configuration configuration, String key) Record a failed forward to the given upstream.voidrecordSuccess(Configuration configuration, String key) Record a successful forward to the given upstream.voidreset()Reset all per-upstream state.
-
Method Details
-
getInstance
-
keyFor
Build the stable per-upstream key from a resolved socket address (host and port only — never the path), returningnullwhen no usable host is available. -
allowRequest
Decide whether a request to the given upstream may proceed.- Closed — always allowed.
- Open and still within the window — rejected (fail fast).
- Open but the window has elapsed (half-open) — exactly one trial request is allowed through; concurrent callers in the same window are rejected.
- Parameters:
key- the upstream key fromkeyFor(InetSocketAddress)(a null/blank key always allows)- Returns:
- true if the request should be forwarded, false to fail fast with a 503
-
recordSuccess
Record a successful forward to the given upstream. Closes the breaker and clears the failure count. No-op when the breaker is disabled or the key is null.A fully-healthy upstream (closed, zero failures, no trial in flight) is evicted from the per-upstream map so a steadily-succeeding upstream leaves no permanent footprint. This bounds the map to currently-degraded upstreams and closes the only growth vector — distinct keys (e.g. via varied client
Hostheaders when no explicit remote address is supplied). Eviction is value-conditional (ConcurrentHashMap.remove(Object, Object)) so a state whose map entry has been replaced is never dropped, and is guarded on the state still being fully healthy. The only thing a concurrentrecordFailure(org.mockserver.configuration.Configuration, java.lang.String)can lose to this is an in-place sub-threshold failure increment on a still-closed breaker, which is benign: the breaker counts consecutive failures since the last success, so a success legitimately resets that count. An entry that a concurrent failure trips open is retained (the health re-check seesopenedAtMillis != 0). -
recordFailure
Record a failed forward to the given upstream. Increments the consecutive-failure count and trips the breaker open once the configured threshold is reached (or immediately re-opens it on a failed half-open trial). No-op when the breaker is disabled or the key is null. -
openCircuitCount
public int openCircuitCount()Number of upstreams whose breaker is currently open (in the open or half-open state). Backs themock_server_upstream_circuit_opengauge. Counts an upstream as open whenever its open timestamp is non-zero, regardless of whether the window has elapsed, so the gauge reflects "this upstream is currently degraded" until a trial request closes it. -
isOpen
True when the breaker for the given key is currently open (open timestamp set). Test/diagnostic helper. -
reset
public void reset()Reset all per-upstream state. Called on server reset and for test isolation.
-