-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Motivation
I am trying to narrow down a production issue where a PoolAcquireTimeoutException is logged after a request has already completed successfully. We are using Spring’s reactive WebClient backed by a Netty HttpClient.
Issue:
The application sends a request, receives a 200 OK response in ~280 ms, and then, after the configured ConnectionProvider#pendingAcquireTimeout (45s), the following is logged:
2025-12-14 16:38:32,199 | | ERROR | 43be4573-0118-4d03-a9c0-835c315a2d9f | N/A | | | r.c.p.Operators | Operator called default onErrorDropped
reactor.netty.internal.shaded.reactor.pool.PoolAcquireTimeoutException: Pool#acquire(Duration) has been pending for more than the configured timeout of 45000ms
at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.run(AbstractPool.java:417)
at io.micrometer.context.ContextSnapshot.lambda$wrap$0(ContextSnapshot.java:91)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
My expectation is that if a connection acquisition was pending, once the connection is successfully acquired the pending countdown should be cancelled.
Reproduction attempt
I have not been able to reproduce this exact scenario locally. However, while experimenting with a saturated pending-acquire queue, I noticed some unexpected behavior:
When the pending queue is full and SimpleDequePool culls pending borrowers with a PoolAcquirePendingLimitException, the borrower countdown does not appear to be stopped via AbstractPool.Borrower#fail. As a result, similar to what we see in production, a PoolAcquireTimeoutException is later triggered after pendingAcquireTimeout elapses.
Expected Behavior
When a connection is successfully acquired or a pending borrower is dropped due to the pool acquire pending limit being reached, the asynchronous acquisition task should be cancelled. As a result, a PoolAcquireTimeoutException should not be thrown.
Actual Behavior
When the pending-acquire queue is full or a connection is successfully acquired, the asynchronous acquisition task is not cancelled. As a result, a PoolAcquireTimeoutException is logged, even though the request has already completed successfully or the borrower has been dropped due to the pending limit.
Steps to Reproduce
Demo: filipovskid/reactor-acquire-cancel-issue-demo
- More information, including logs, can be found in the README.md
I was only able to reproduce the issue where a PoolAcquireTimeoutException is thrown after a borrower gets culled when the pending acquisition queue is full.
Steps taken for the reproducible part:
- Configure a WebClient backed by a Reactor Netty
ConnectionProviderwith a limited connection pool. - Saturate the pool’s pending-acquire queue to trigger a
PoolAcquirePendingLimitException. - Observe that the asynchronous acquisition task is not cancelled, which may later result in a
PoolAcquireTimeoutException.
Your Environment
- Reactor version(s) used:
- Other relevant libraries versions (eg.
netty, ...):
io.projectreactor.netty:reactor-netty-core:jar:1.2.8
io.projectreactor:reactor-core:jar:3.7.8
io.projectreactor.netty:reactor-netty-http:jar:1.2.8
io.netty:<>:jar:4.1.123.Final
- JVM version (
java -version):
openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Zulu21.34+19-CA (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Zulu21.34+19-CA (build 21.0.3+9-LTS, mixed mode, sharing)
- OS and version (eg
uname -a):
Darwin mb5489 25.1.0 Darwin Kernel Version 25.1.0: Mon Oct 20 19:33:36 PDT 2025; root:xnu-12377.41.6~2/RELEASE_ARM64_T6030 arm64