NIOConnectionPool connectionPoolExhausted: Immediate Failure Versus Back-Pressure Semantics
0 reputation · 03 Oct 2021, 19:24 UTC
0 reputation · 03 Oct 2021, 19:24 UTC
SwiftNIO's NIOConnectionPool throws ConnectionPoolError.connectionPoolExhausted when all pooled connections are in use and no idle connection is available for a new request. The error is surfaced through the ChannelFuture's failure handler, allowing developers to detect intermittent exhaustion under load. Because the pool size is fixed at initialization and does not automatically grow, exhaustion indicates that the configured maxConnections is insufficient for the current concurrency pattern.
An unresolved behavior concerns whether the pool should back-pressure incoming requests by queuing them until a connection frees up, or continue to fail immediately with .connectionPoolExhausted. The current implementation chooses immediate failure, but the design discussion remains open. Adjusting the pool size after creation requires recreating the NIOConnectionPool, which adds operational complexity when tuning concurrency limits.
What are the intended semantics for .connectionPoolExhausted in SwiftNIO's connection pool design? Should callers treat it as a retryable resource-limit signal or as a hard failure? Is there a documented pattern for safely recreating the pool without disrupting in-flight requests?
35275 reputation · 03 Oct 2021, 20:53 UTC
ConnectionPoolError.connectionPoolExhausted is an immediate-failure, transient resource-limit signal, not a hard failure. SwiftNIO’s fixed-size pool does not queue or back-pressure new requests when every connection is busy; it fails the new request’s ChannelFuture immediately. Callers should treat it as retryable, typically with back-off or application-level throttling, rather than as a fatal connection error.
| Item | Status | Note |
|---|---|---|
Fixed maxConnections at initialization | Confirmed for SwiftNIO 2.x | Pool does not grow automatically. |
| Immediate failure on exhaustion | Confirmed for current implementation | No built-in request queue. |
| Retryable semantics | Assumed from design intent | Treat as transient; verify release notes. |
| Swap-and-drain pool replacement | Application-level pattern | Not an official SwiftNIO hot-resize feature. |
ConnectionPoolError.connectionPoolExhausted in the future’s failure handler.maxConnections by recreating the pool.SwiftNIO does not provide a documented runtime resize operation. The safe approach is to create a replacement pool, atomically swap the reference, wait for the old pool’s active request count to reach zero, then close the old pool.
// Illustrative only; verify exact API against your SwiftNIO version.
let replacement = NIOConnectionPool(maxConnections: newLimit, ...)
let previous = self.pool
self.pool = replacement // perform on a serial queue or actor
previous.close() // call only after activeCount is 0
maxConnections.maxConnections smaller than your concurrent request burst.connectionPoolExhausted.Which SwiftNIO major version are you deploying? The pool API and shutdown behavior can differ between versions, and the swap-and-drain steps should be verified against your release’s source or release notes.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.