Skip to content

Conversation

USEONGEE
Copy link

@USEONGEE USEONGEE commented Aug 10, 2025

Closes #191

Title

Add ReconnectableWebsocketManager with automatic reconnection, subscription restoration, and persistent app-level ping

Summary

This PR introduces ReconnectableWebsocketManager, extending WebsocketManager to automatically reconnect on disconnection and restore subscriptions after the connection is re-established. It also ensures the application-level ping continues across reconnects.

Note

This PR does not modify the original WebsocketManager implementation; all changes are encapsulated in the new ReconnectableWebsocketManager

Changes

  • ReconnectableWebsocketManager
    • Reconnection loop with configurable ping_timeout, ping_interval, and reconnect_interval.
    • on_close / on_error trigger reconnection unless stop_event is set.
    • _reconnect() re-queues previously active subscriptions; on_open() drains the queue and re-subscribes.
  • App-level ping persistence
    • Override send_ping() so the ping thread does not terminate when the socket drops; it skips sends while disconnected and resumes automatically after reconnect.
    • Ensure the ping thread is started initially and restarted if needed via _start_ping_sender().
  • Minor: log messages reflect the actual reconnect_interval.

Why

  • The original WebsocketManager does not provide reconnection or subscription restoration. This PR improves resilience under network instability and server restarts, and maintains application-level heartbeats across reconnects.

Out of Scope

  • Thread-safety/locking for shared structures (queued_subscriptions, active_subscriptions, subscription_id_counter).
  • Actor/queue refactor and async-specific APIs.

@USEONGEE USEONGEE closed this Aug 10, 2025
The previous commit mistakenly modified the original send_ping() method
in WebsocketManager. This change restores the method to its original
implementation so that the base class remains unmodified.

This ensures that the upcoming PR for ReconnectableWebsocketManager
remains self-contained and does not alter the behavior of the
original WebsocketManager.
@USEONGEE USEONGEE reopened this Aug 10, 2025
@USEONGEE
Copy link
Author

In the WebsocketManager constructor, the ws_url variable is not stored as an instance field (no self.ws_url).
In the newly implemented ReconnectableWebsocketManager, the run method declares ws_url as a local variable.
This inconsistency could lead to confusion in the future, so I would like to store ws_url as an instance field in WebsocketManager

@USEONGEE USEONGEE changed the title Add reconnectable websocket manager Add reconnectable websocket manager Aug 10, 2025
@rafaelcapucho
Copy link

I'm having hard time not being able to recover from lost connection too.

The websocket.WebSocketApp(..) Is so deep that it is hard to patch it, to add the on_error= call.

Also we can't catch the exception in any way, like as in:

def main():
    #app = HyperLiquidApp()
    #app.run()

    while run:
        try:
            address, info, exchange = utils.setup(constants.MAINNET_API_URL, skip_ws=False)

        except WebSocketException:
            continue

So one alternative should be offered by the this library. I'm waiting to a solution, thank you !!

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.

WebsocketManager lacks reconnection and subscription restoration

2 participants