Class ParseTimeout
One instance per top-level task, created from TimeoutLimits and looked up from the
ParseContext at every nesting depth, so a budget request from an embedded document
(e.g. OCR on an image inside a zip inside a PDF) draws from the same remaining time as the
top-level task -- no per-depth bookkeeping needed.
All public accessors are relative to the task (elapsed/remaining/since-last-progress), not
anchored to wall-clock time -- internally this is backed by System.nanoTime(), so
a system clock adjustment mid-task doesn't affect it.
Runtime-only state (not Serializable); never sent over the wire.
Two responsibilities:
budgetFor(long)-- caps a requested budget at whatever remains of the task:min(requested, remaining).checkpoint()-- records progress. Bounded waits (e.g.ProcessUtils.execute(java.lang.ProcessBuilder, long, int, int)) checkpoint periodically so a long but legitimate external call isn't mistaken for a hang by the stall detector.
- Since:
- Apache Tika 4.0
-
Method Summary
Modifier and TypeMethodDescriptionlongbudgetFor(long requestedMillis) The single composition rule for nested timeouts: a requested budget is never granted more time than remains for the whole task.voidRecords that progress happened.static voidcheckpoint(ParseContext context) Records a checkpoint on the ParseTimeout in the given context, if present.longstatic ParseTimeoutgetOrCreate(ParseContext context) Returns the ParseTimeout installed in the given context, creating and installing one (fromTimeoutLimits.get(ParseContext)) if absent.longlonglonglongstatic ParseTimeoutstart(TimeoutLimits limits) Starts a new timeout window anchored to now, using the total and progress timeouts from the given limits.
-
Method Details
-
start
Starts a new timeout window anchored to now, using the total and progress timeouts from the given limits.Rejects negative totals/progress (no coherent "less than no time"). Zero is accepted when both are zero (a task resuming with none of its budget left, which expires immediately). A progress timeout of zero with a positive total is rejected: it is never intended and would fire the stall detector immediately, killing every task despite the remaining total budget. A progress timeout at or above a positive total is accepted but logged, since the stall detector could then never fire before the total deadline.
- Throws:
IllegalArgumentException- if either limit is negative, or the progress timeout is zero while the total is positive
-
getOrCreate
Returns the ParseTimeout installed in the given context, creating and installing one (fromTimeoutLimits.get(ParseContext)) if absent. Idempotent: the same instance is reused for every call with the same context, including nested embedded-document calls.- Parameters:
context- the ParseContext, may be null- Returns:
- the task's ParseTimeout, or a detached default if context is null
-
checkpoint
Records a checkpoint on the ParseTimeout in the given context, if present. UnlikegetOrCreate(ParseContext), this does not install one -- a checkpoint from code outside any tracked task is simply a no-op.- Parameters:
context- the ParseContext, may be null
-
budgetFor
public long budgetFor(long requestedMillis) The single composition rule for nested timeouts: a requested budget is never granted more time than remains for the whole task.Also the chokepoint for misconfiguration diagnostics -- every per-parser timeout flows through here, so validation lives once instead of per config class:
- a non-positive request is treated as "unset" (falls back to remaining task time) instead of granting zero, which would fail instantly with no useful diagnostic;
- a request under one second is logged -- usually a seconds-vs-milliseconds mistake;
- a request larger than the task's original total is logged, since it can never be granted in full even at the task's start (unlike the ordinary case of being clipped by elapsed time, which is not logged).
- Returns:
min(requestedMillis, remainingMillis()), or justremainingMillis()ifrequestedMilliswas non-positive
-
getTotalTimeoutMillis
public long getTotalTimeoutMillis()- Returns:
- the task's original total timeout in milliseconds, or
Long.MAX_VALUEif unbounded -- unlikeremainingMillis(), this does not shrink over time
-
elapsedMillis
public long elapsedMillis()- Returns:
- milliseconds elapsed since the task started
-
remainingMillis
public long remainingMillis()- Returns:
- milliseconds remaining before the task's total timeout, never negative
-
checkpoint
public void checkpoint()Records that progress happened. Never throws — cooperative cancellation on an exhausted deadline happens at embedded-document boundaries (seeParseRecord), not here. -
millisSinceLastProgress
public long millisSinceLastProgress()- Returns:
- milliseconds elapsed since the last checkpoint
-
getProgressTimeoutMillis
public long getProgressTimeoutMillis()- Returns:
- the configured progress (stall-detection) timeout in milliseconds
-