This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch fix-flaky-on-jenkins-test
in repository https://gitbox.apache.org/repos/asf/tika.git

commit 93bc35aac04babd047c498cb21183041f7dfc657
Author: tallison <[email protected]>
AuthorDate: Wed Jun 24 17:53:23 2026 -0400

    Allow more time for startup to fix jenkins failures
---
 .../java/org/apache/tika/pipes/core/PipesClient.java   |  8 ++++++--
 .../java/org/apache/tika/pipes/core/PipesConfig.java   | 18 ++++++++++++++++++
 .../org/apache/tika/pipes/core/PipesClientTest.java    |  8 ++++----
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git 
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
 
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
index e274117564..1df7caec4b 100644
--- 
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
+++ 
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
@@ -304,8 +304,10 @@ public class PipesClient implements Closeable {
         int port = serverManager.getPort();
         LOG.debug("pipesClientId={}: connecting to server", pipesClientId);
 
-        // Connect to server
-        Socket socket = serverManager.connect((int) 
pipesConfig.getSocketTimeoutMs());
+        // Connect to server. Use the generous startup timeout as the read 
SO_TIMEOUT so the
+        // server's post-connect initialization and READY handshake aren't 
bounded by the
+        // (possibly tight) per-request socketTimeoutMs.
+        Socket socket = serverManager.connect((int) 
pipesConfig.getStartupTimeoutMs());
 
         synchronized (connectionLock) {
             connectionTuple = new ConnectionTuple(socket,
@@ -314,6 +316,8 @@ public class PipesClient implements Closeable {
         }
 
         waitForStartup();
+        // Server is ready; subsequent reads use the normal per-request socket 
timeout.
+        socket.setSoTimeout((int) pipesConfig.getSocketTimeoutMs());
     }
 
     private void writeTask(FetchEmitTuple t) throws IOException {
diff --git 
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesConfig.java
 
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesConfig.java
index fd1d19d566..c0dd1247ea 100644
--- 
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesConfig.java
+++ 
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesConfig.java
@@ -37,6 +37,8 @@ public class PipesConfig {
 
     public static final long DEFAULT_SOCKET_TIMEOUT_MS = 60000;
 
+    public static final long DEFAULT_STARTUP_TIMEOUT_MS = 60000;
+
     public static final long DEFAULT_HEARTBEAT_INTERVAL_MS = 1000;
 
     public static final boolean DEFAULT_USE_SHARED_SERVER = false;
@@ -55,6 +57,7 @@ public class PipesConfig {
     private boolean useSharedServer = DEFAULT_USE_SHARED_SERVER;
 
     private long socketTimeoutMs = DEFAULT_SOCKET_TIMEOUT_MS;
+    private long startupTimeoutMs = DEFAULT_STARTUP_TIMEOUT_MS;
     private long heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL_MS;
 
     private long shutdownClientAfterMillis = 
DEFAULT_SHUTDOWN_CLIENT_AFTER_MILLS;
@@ -161,6 +164,21 @@ public class PipesConfig {
         this.socketTimeoutMs = socketTimeoutMs;
     }
 
+    public long getStartupTimeoutMs() {
+        return startupTimeoutMs;
+    }
+
+    /**
+     * Timeout in milliseconds for the forked server to start up and send its 
READY handshake.
+     * Distinct from {@link #getSocketTimeoutMs()}: cold-starting the forked 
JVM (loading config,
+     * parsers and plugins) can take far longer than a normal per-read 
timeout, so the handshake
+     * gets its own generous budget. Once the server is ready, reads switch to 
{@code socketTimeoutMs}.
+     * @param startupTimeoutMs
+     */
+    public void setStartupTimeoutMs(long startupTimeoutMs) {
+        this.startupTimeoutMs = startupTimeoutMs;
+    }
+
     public long getHeartbeatIntervalMs() {
         return heartbeatIntervalMs;
     }
diff --git 
a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java
 
b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java
index d3189f0bf1..011d1688e5 100644
--- 
a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java
+++ 
b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java
@@ -396,13 +396,13 @@ public class PipesClientTest {
             PipesResult pipesResult = pipesClient.process(tuple);
             long elapsed = System.currentTimeMillis() - startTime;
 
-            // Should timeout due to socket timeout (no heartbeats received 
within socketTimeoutMs)
-            // fails with FAILED_TO_INITIALIZE when using mchange-commons-java 
0.5.0
+            // Should timeout due to socket timeout (no heartbeats received 
within socketTimeoutMs).
+            // Startup/handshake is bounded by startupTimeoutMs (not 
socketTimeoutMs), so a slow
+            // fork cold-start no longer misfires here as FAILED_TO_INITIALIZE.
             assertEquals(PipesResult.RESULT_STATUS.TIMEOUT, 
pipesResult.status(),
                     "Should timeout when socket times out");
 
-            // Socket timeout is 3 seconds; allow generous headroom for slow 
CI runners
-            // where the server may need multiple startup attempts before 
connecting.
+            // Socket timeout is 3 seconds; allow generous headroom for slow 
CI runners.
             assertTrue(elapsed < 60000,
                     "Socket timeout should occur within 60s (elapsed: " + 
elapsed + "ms)");
 

Reply via email to