Confluence 8.0 request timeout transition and async indexing cleanup boundary
0 reputation · 23 Aug 2025, 16:48 UTC
0 reputation · 23 Aug 2025, 16:48 UTC
Confluence 8.0 introduced the system property confluence.request.timeout.seconds (default 300) to cap how long Tomcat keeps an HTTP request open before returning a 504 Gateway Timeout. When that timeout fires, the HTTP thread is aborted, but asynchronous tasks spawned by the request—such as content indexing or search reindex—are not automatically interrupted. As of Confluence 8.5.x, it remains an open question whether the server propagates InterruptedException to plugin-provided Callable tasks submitted via SpringTaskExecutor; current behavior appears to swallow the interrupt flag, though this warrants verification against the latest source.
This creates a compatibility boundary between the HTTP request lifecycle and background executor cleanup. REST clients can detect a 504 response and retry, but there is no guaranteed cleanup of server-side resources, leading to possible thread-pool leakage under high load when the searchIndexing executor retains active threads.
Does Confluence 8.5.x propagate interrupt signals to plugin-provided Callable tasks submitted via SpringTaskExecutor when confluence.request.timeout.seconds expires? What is the documented behavior for the searchIndexing executor's thread pool after a client receives a 504 Gateway Timeout? Are there version-specific compatibility notes for adjusting confluence.request.timeout.seconds alongside confluence.indexing.thread.pool.size?
Confluence 8.5.x does not document guaranteed interrupt propagation to plugin-provided Callable tasks submitted via SpringTaskExecutor when confluence.request.timeout.seconds expires. Treat the interrupt as not propagated until you verify it in your environment.
Well-established:
504 Gateway Timeout.confluence.request.timeout.seconds and confluence.indexing.thread.pool.size are independent settings; changing one does not automatically adjust the other.Likely explanation (unconfirmed for 8.5.x):
Callable tasks ran to completion unless they manually checked Thread.interrupted(). Whether 8.5.x changed this is not explicitly documented.searchIndexing executor is expected to retain any threads that were active when the timeout occurred; those threads return to the pool only when the current task finishes. Under sustained 504 conditions, this can lead to pool exhaustion.There are no published compatibility notes that couple confluence.request.timeout.seconds with confluence.indexing.thread.pool.size. Because the settings are independent, a low timeout combined with a small indexing pool increases the risk of stranded threads. Raising the timeout without monitoring the pool can mask exhaustion.
Thread.interrupted() or use a cooperative cancellation token inside your plugin Callable.searchIndexing threads show an interrupted status.com.atlassian.confluence.spring.SpringTaskExecutor and org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.Can you confirm whether your plugin-provided Callable already polls Thread.interrupted(), or whether you are observing searchIndexing threads persisting after a 504? If the task does not check for interruption, add cooperative cancellation first. If it already does and threads still persist, inspect the SpringTaskExecutor configuration and rejection policy for your 8.5.x instance.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.