This is an automated email from the ASF dual-hosted git repository.
tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new 6b4e9368dd TIKA-4919: improve logging when progress==totaltasktimeout
(#3228)
6b4e9368dd is described below
commit 6b4e9368ddfcfac91ed95d8d7e6f259bc776bcd2
Author: Tim Allison <[email protected]>
AuthorDate: Thu Sep 24 05:59:48 2026 -0400
TIKA-4919: improve logging when progress==totaltasktimeout (#3228)
---
docs/modules/ROOT/pages/pipes/timeouts.adoc | 5 ++++-
.../main/java/org/apache/tika/config/ParseTimeout.java | 7 +------
.../main/java/org/apache/tika/config/TimeoutLimits.java | 15 ++++++++++++++-
.../java/org/apache/tika/config/TimeoutLimitsTest.java | 8 ++++++++
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/docs/modules/ROOT/pages/pipes/timeouts.adoc
b/docs/modules/ROOT/pages/pipes/timeouts.adoc
index 4613f8397c..2b983ee67d 100644
--- a/docs/modules/ROOT/pages/pipes/timeouts.adoc
+++ b/docs/modules/ROOT/pages/pipes/timeouts.adoc
@@ -27,7 +27,10 @@ Three timeout settings bound a parse, and each answers a
different question:
including all of its embedded documents. Default: `3600000` (1 hour).
* **`progressTimeoutMillis`** -- How long may the parse go *silent* before it
is
- considered hung and killed. Default: `120000` (2 minutes).
+ considered hung and killed. Default: `120000` (2 minutes). To turn stall
detection
+ off and keep only the total deadline, set it equal to
`totalTaskTimeoutMillis`.
+ Don't use `0` (rejected when the total is positive) or `Long.MAX_VALUE` (it
also
+ removes the pipes client's backstop for a wedged server).
* **Per-parser timeouts** (e.g., `tesseract-ocr-parser.timeoutMillis`) -- How
long may
*one call* to that parser's external process or service take.
diff --git a/tika-core/src/main/java/org/apache/tika/config/ParseTimeout.java
b/tika-core/src/main/java/org/apache/tika/config/ParseTimeout.java
index df95726f46..3769b3779d 100644
--- a/tika-core/src/main/java/org/apache/tika/config/ParseTimeout.java
+++ b/tika-core/src/main/java/org/apache/tika/config/ParseTimeout.java
@@ -81,8 +81,7 @@ public class ParseTimeout implements TransientParseState {
* immediately). A progress timeout of zero with a <em>positive</em> 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.
+ * accepted and disables the stall detector.
*
* @throws IllegalArgumentException if either limit is negative, or the
progress timeout is
* zero while the total is positive
@@ -101,10 +100,6 @@ public class ParseTimeout implements TransientParseState {
+ "totalTaskTimeoutMillis (" + total + ") would kill every
task immediately; "
+ "use a positive progress timeout");
}
- if (total > 0 && progress >= total) {
- LOG.warn("progressTimeoutMillis ({}) >= totalTaskTimeoutMillis
({}) -- the stall " +
- "detector can never fire before the total deadline does",
progress, total);
- }
if (total > 0 && total < 1000) {
LOG.warn("totalTaskTimeoutMillis ({}) is under one second -- this
is often a " +
"seconds-vs-milliseconds mistake in the configuration",
total);
diff --git a/tika-core/src/main/java/org/apache/tika/config/TimeoutLimits.java
b/tika-core/src/main/java/org/apache/tika/config/TimeoutLimits.java
index 0c20d1e92a..90490744da 100644
--- a/tika-core/src/main/java/org/apache/tika/config/TimeoutLimits.java
+++ b/tika-core/src/main/java/org/apache/tika/config/TimeoutLimits.java
@@ -18,6 +18,9 @@ package org.apache.tika.config;
import java.io.Serializable;
import java.util.Objects;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.apache.tika.annotation.TikaComponent;
import org.apache.tika.exception.TikaConfigException;
import org.apache.tika.parser.ParseContext;
@@ -30,7 +33,9 @@ import org.apache.tika.parser.ParseContext;
* any embedded documents it recurses into
* (default: 3,600,000 ms = 1 hour)</li>
* <li>{@code progressTimeoutMillis} — bounds time since the last progress
update;
- * catches infinite loops and hung processes (default: 120,000 ms = 2
minutes)</li>
+ * catches infinite loops and hung processes (default: 120,000 ms = 2
minutes).
+ * Set it equal to {@code totalTaskTimeoutMillis} to disable stall
detection and keep
+ * only the total deadline; {@code 0} is rejected when the total is
positive.</li>
* <li>{@code throwOnDeadline} — whether reaching the total timeout
mid-parse throws
* (via {@link org.apache.tika.exception.EmbeddedLimitReachedException})
instead of
* skipping remaining embedded documents and returning content extracted
so far
@@ -63,6 +68,8 @@ public class TimeoutLimits implements Serializable,
Initializable {
private static final long serialVersionUID = 2L;
+ private static final Logger LOG =
LoggerFactory.getLogger(TimeoutLimits.class);
+
public static final long DEFAULT_TOTAL_TASK_TIMEOUT_MILLIS = 3_600_000L;
public static final long DEFAULT_PROGRESS_TIMEOUT_MILLIS = 120_000L;
@@ -148,6 +155,12 @@ public class TimeoutLimits implements Serializable,
Initializable {
+ "totalTaskTimeoutMillis (" + totalTaskTimeoutMillis
+ ") would kill every task immediately; use a positive
progress timeout");
}
+ // equal is the documented way to disable stall detection, so only
warn above it
+ if (totalTaskTimeoutMillis > 0 && progressTimeoutMillis >
totalTaskTimeoutMillis) {
+ LOG.warn("progressTimeoutMillis ({}) > totalTaskTimeoutMillis ({})
-- the stall "
+ + "detector can never fire; set them equal to disable it
deliberately",
+ progressTimeoutMillis, totalTaskTimeoutMillis);
+ }
}
/**
diff --git
a/tika-core/src/test/java/org/apache/tika/config/TimeoutLimitsTest.java
b/tika-core/src/test/java/org/apache/tika/config/TimeoutLimitsTest.java
index ab3f59f8c6..c79404bb4e 100644
--- a/tika-core/src/test/java/org/apache/tika/config/TimeoutLimitsTest.java
+++ b/tika-core/src/test/java/org/apache/tika/config/TimeoutLimitsTest.java
@@ -44,4 +44,12 @@ public class TimeoutLimitsTest {
assertDoesNotThrow(new TimeoutLimits(0, 0)::initialize);
assertDoesNotThrow(new TimeoutLimits()::initialize);
}
+
+ /** progress == total is the supported way to disable stall detection. */
+ @Test
+ public void testProgressEqualToTotalIsValid() {
+ TimeoutLimits limits = new TimeoutLimits(60_000, 60_000);
+ assertDoesNotThrow(limits::initialize);
+ assertDoesNotThrow(() -> ParseTimeout.start(limits));
+ }
}