One Event-Loop Turn, One False Redis Capacity Error
This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry . Project Overview redis-py is the Python client for Redis. Its asynchronous cluster implementation maintains a per-node connection pool with an in-use set, a free queue, and optional max_connections capacity. The bug was not a leaked connection or a deadlock. It was one event-loop turn in which a usable pool slot…
The bug was caused by a single iteration of the event loop where a usable connection slot in the asynchronous cluster implementation of redis-py existed in neither the in-use set nor the free queue. The issue did not stem from leaked connections or deadlocks but rather a race condition during the connection release process.
The solution, implemented in PR #4256 for redis-py, maintains the background disconnect for open connections and clears a stale flag if the connection is already closed. This prevents scheduling a no-op disconnect for closed connections, thus preserving the safety rule that marked, connected sockets should not be returned to circulation.
To demonstrate the bug, a regression test was created that drives the ClusterNode.execute_command() with a scripted connection and uses asyncio.Event objects to control the interleaving of commands and events. This test confirms that the issue can occur during the real production control flow and not just in a manually set flag scenario.
After the fix, an already-closed connection that has been re-marked returns immediately to the free queue upon release, avoiding false capacity errors. The pool no longer reports exhaustion due to a no-op background task not receiving its event-loop turn yet. This focused cluster connection-handling change resolves the issue without introducing new public methods, retry policies, timeouts, or queues.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — it may contain errors, so check the original before relying on it.