Class MatchingTimeoutExecutor
The pool is multi-threaded (not single-thread) so concurrent matches do not serialize, and daemon-flagged so it never blocks JVM shutdown.
The pool is bounded rather than unbounded-cached: an unbounded cached pool would spawn
one thread per concurrent match, so a burst of slow (ReDoS) patterns under load could create
thousands of threads and exhaust memory — turning the DoS protection into a DoS amplifier. The
bounded pool caps live evaluator threads at a generous max(64, availableProcessors * 16);
a SynchronousQueue means there is no work backlog, so a task either gets a thread
immediately (creating one up to the cap) or — only under extreme saturation beyond the cap — is
rejected.
Rejection must never corrupt a match result. A rejected submission is NOT
treated as a timeout (which would turn a would-be match into a silent non-match). Instead the
task is run inline on the calling thread and its real result returned. This deliberately
sacrifices the per-call timeout / DoS-isolation guarantee for that one call (the inline regex
could in theory pin the calling thread), but only when more than max(64, cores*16)
evaluations are already in flight — a regime where correctness of the result is far more
important than timeout isolation for a mock server. The generous cap makes this path effectively
unreachable under realistic concurrency; when it does fire it logs a distinct WARN so operators
can detect saturation.
-
Nested Class Summary
Nested Classes -
Method Summary
Modifier and TypeMethodDescriptionstatic <T> TcallWithTimeout(Callable<T> task, long timeoutMillis, T onTimeout, MatchingTimeoutExecutor.OnTimeout onTimeoutCallback) Run a matching task with a millisecond timeout.static booleanmatchesWithRegexTimeout(MockServerLogger mockServerLogger, String description, Pattern pattern, Callable<Boolean> matchOperation) Evaluate a user-supplied regular expression under the sharedmockserver.regexMatchingTimeoutMillistimeout, so a pathological (ReDoS) pattern cannot pin a worker thread.
-
Method Details
-
callWithTimeout
public static <T> T callWithTimeout(Callable<T> task, long timeoutMillis, T onTimeout, MatchingTimeoutExecutor.OnTimeout onTimeoutCallback) throws Exception Run a matching task with a millisecond timeout. A non-positive timeout disables the timeout and runs the task on the calling thread (preserving pre-timeout behaviour for users who opt out).- Returns:
- the task's result, or
onTimeoutwhen the timeout fires - Throws:
Exception- any checked exception thrown by the task (other than TimeoutException)
-
matchesWithRegexTimeout
public static boolean matchesWithRegexTimeout(MockServerLogger mockServerLogger, String description, Pattern pattern, Callable<Boolean> matchOperation) Evaluate a user-supplied regular expression under the sharedmockserver.regexMatchingTimeoutMillistimeout, so a pathological (ReDoS) pattern cannot pin a worker thread. A timeout or any error is treated as a non-match (returnsfalse) and, when a timeout fires and a logger is supplied, logs a WARN naming the pattern.- Parameters:
mockServerLogger- logger for the timeout warning (may be null)description- short label for the log (e.g. "graphql operationName")pattern- the compiled user regex (used only for the log message)matchOperation- the actual match call (e.g.() -> pattern.matcher(input).matches())- Returns:
- the match result, or
falseon timeout/error
-