Skip to content

Conversation

@wish4679
Copy link

Summary

Fixes a task leak in KeepAliveWebsocket where reconnection events create duplicate keepalive loops that continue running indefinitely, leading to resource exhaustion and redundant API calls.


Problem

The current implementation has a critical issue where the keepalive loop is not properly stopped during reconnection or cleanup:

Root Cause:

  1. The keepalive machanism uses a self-perpetuating loop: _start_socket_timer() -> (timeout delay) -> _keepalive_socket() -> finally: _start_socket_timer() -> ...
  2. When reconnection occurs via _after_connect(), a new loop is unconditionally started even if the previous loop is still running
  3. The previous keepalive task continues executing in the background and restarts its own timer in the finally block
  4. Each reconnection creates an additional orphaned keepalive loop

Consequences:

  • Multiple concurrent keepalive tasks making redundant listen key refresh API calls
  • Increased resource usage (memory, event loop tasks, network traffic)
  • Potential rate limiting issues with Binance API
  • Memory leak that grows with each reconnection

Solution

Implement a sentinel-based approach using self._timer to prevent duplicate loop:

  1. In _after_connect(): Only start a new keepalive loop if one isn't already running
  2. In _keepalive_socket() finally block: Only restart the loop if not being shut down (i.e., self._timer is not None)

This ensures:

  • No duplicate loop: Reconnection reuses existing keepalive tasks
  • Clean shutdown: When __aexit__() sets self._timer = None, the finally block stops restarting

@wish4679 wish4679 requested a review from carlosmiei as a code owner November 27, 2025 02:40
@pcriadoperez
Copy link
Collaborator

Thanks for the contribution @wish4679! closing thir PR as will be doing change in #1637

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.

2 participants