Skip to content

Conversation

@NoneGG
Copy link
Owner

@NoneGG NoneGG commented Dec 29, 2025

Fixes critical bugs and modernizes asyncio usage for improved robustness and compatibility.

This PR addresses several P0 issues identified in the project, including:

  • Removing deprecated loop= parameters from asyncio calls to ensure compatibility with Python 3.8+.
  • Correcting the await logic for asynchronous callbacks in pipelines.
  • Fixing a potential infinite loop or non-execution bug in Cache.delete_pattern's SCAN cursor handling.
  • Enhancing exception chaining in connection errors to preserve root causes.
  • Improving the robustness of connection pool idle-check background tasks by ensuring proper scheduling and cancellation.
  • Making connection pool disconnect() operations more idempotent.
  • Updating PubSubWorkerThread to use concurrent.futures.wait instead of deprecated asyncio.wait(loop=...).

Open in Cursor Open in Web


Note

Modernizes asyncio integration and fixes several correctness issues across cache, pipeline, connections, pools, and pubsub.

  • Updates asyncio calls to avoid deprecated loop= parameters (asyncio.sleep, open_connection, open_unix_connection, timeouts, thread waits) gated by LOOP_DEPRECATED; uses concurrent.futures.wait in PubSubWorkerThread.stop
  • Fixes Cache.delete_pattern SCAN loop: start cursor=0, iterate until cursor==0, and guard deletes when no identities
  • Corrects pipeline response handling: await callbacks only when inspect.isawaitable(r)
  • Enhances error context: Connection.connect() now raises ConnectionError with exception chaining (from exc)
  • Connection pool robustness: schedule idle-reaper tasks on the appropriate loop, track/cancel them on disconnect(), and fully reset internal state; make cluster pool variants consistent and resilient to missing entries during removal
  • Removes deprecated loop arguments in transaction retry sleeps and Lock sleep; minor cleanups to avoid negative counters and ensure idempotent disconnect behavior

Written by Cursor Bugbot for commit 61f0b8a. This will update automatically on new commits. Configure here.

Co-authored-by: jason0916phoenix <jason0916phoenix@gmail.com>
@cursor
Copy link

cursor bot commented Dec 29, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@NoneGG NoneGG marked this pull request as ready for review January 5, 2026 12:16
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

try:
conn_list.remove(connection)
except ValueError:
pass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition causes KeyError in idle check task

In ClusterConnectionPool.disconnect_on_idle_time_exceeded(), the access to _created_connections_per_node[node['name']] at line 369 is unprotected, while the similar access to _available_connections was made safe with .get() and try/except. The new disconnect() method clears _created_connections_per_node = {} after calling task.cancel(), but cancellation only raises CancelledError at the next await point. Since there's no await between the condition check and the decrement, a racing idle check task can attempt to access the cleared dict, causing a KeyError. The decrement needs the same protection pattern as the list removal above it.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants