From 84a1c265cea6ddc59c5dc4b43f756af7090e8cf8 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Tue, 11 May 2021 16:24:02 -0400 Subject: [PATCH] Improved Radarr SignalR feed reconnection process. --- bazarr/signalr_client.py | 55 +++++++++---------- libs/signalrcore/hub/base_hub_connection.py | 10 ++++ libs/signalrcore/transport/base_transport.py | 7 ++- .../websockets/websocket_transport.py | 9 +++ libs/version.txt | 2 +- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/bazarr/signalr_client.py b/bazarr/signalr_client.py index 0e3467581..d06e1144a 100644 --- a/bazarr/signalr_client.py +++ b/bazarr/signalr_client.py @@ -75,55 +75,50 @@ class SonarrSignalrClient(threading.Thread): class RadarrSignalrClient(threading.Thread): def __init__(self): super(RadarrSignalrClient, self).__init__() - self.stopped = True self.apikey_radarr = None self.connection = None + self.configure() + self.start() + + def start(self): + logging.debug('BAZARR connecting to Radarr SignalR feed...') + self.connection.start() + gevent.sleep() + def stop(self): - self.connection.stop() - self.stopped = True logging.info('BAZARR SignalR client for Radarr is now disconnected.') + self.connection.stop() def restart(self): - if not self.stopped: + if self.connection.transport.state.value in [0, 1, 2]: self.stop() if settings.general.getboolean('use_radarr'): - self.run() + self.configure() + self.start() - def run(self): + def configure(self): self.apikey_radarr = settings.radarr.apikey self.connection = HubConnectionBuilder() \ .with_url(url_radarr() + "/signalr/messages?access_token={}".format(self.apikey_radarr), options={ "verify_ssl": False - }).build() - self.connection.on_open(lambda: logging.debug("BAZARR SignalR client for Radarr is connected.")) - self.connection.on_close(lambda: logging.debug("BAZARR SignalR client for Radarr is disconnected.")) + }) \ + .with_automatic_reconnect({ + "type": "raw", + "keep_alive_interval": 5, + "reconnect_interval": 5, + "max_attempts": None + }).build() + self.connection.on_open(lambda: logging.info('BAZARR SignalR client for Radarr is connected and waiting for ' + 'events.')) + self.connection.on_reconnect(lambda: logging.info('BAZARR SignalR client for Radarr connection as been lost. ' + 'Trying to reconnect...')) + self.connection.on_close(lambda: logging.debug('BAZARR SignalR client for Radarr is disconnected.')) self.connection.on_error(lambda data: logging.debug(f"BAZARR SignalR client for Radarr: An exception was thrown" f" closed{data.error}")) self.connection.on("receiveMessage", dispatcher) - while True: - if not self.stopped: - return - if self.connection.transport.state.value == 4: - # 0: 'connecting', 1: 'connected', 2: 'reconnecting', 4: 'disconnected' - try: - logging.debug('BAZARR connecting to Radarr SignalR feed...') - self.connection.start() - except ConnectionError: - logging.error('BAZARR connection to Radarr SignalR feed has been lost. Reconnecting...') - gevent.sleep(15) - pass - else: - self.stopped = False - logging.info('BAZARR SignalR client for Radarr is connected and waiting for events.') - if not args.dev: - scheduler.execute_job_now('update_movies') - gevent.sleep() - else: - gevent.sleep(5) - def dispatcher(data): topic = media_id = action = None diff --git a/libs/signalrcore/hub/base_hub_connection.py b/libs/signalrcore/hub/base_hub_connection.py index c9325bf63..f5c3dc342 100644 --- a/libs/signalrcore/hub/base_hub_connection.py +++ b/libs/signalrcore/hub/base_hub_connection.py @@ -77,6 +77,16 @@ class BaseHubConnection(object): """ self._on_error = callback + def on_reconnect(self, callback): + """Configures on_reconnect reconnection callback. + It will be raised on reconnection event + connection.on_reconnect(lambda: print( + "connection lost, reconnection in progress ")) + Args: + callback (function): function without params + """ + self.transport.on_reconnect_callback(callback) + def on(self, event, callback_function: Callable): """Register a callback on the specified event Args: diff --git a/libs/signalrcore/transport/base_transport.py b/libs/signalrcore/transport/base_transport.py index c73a2c028..eeb3f7431 100644 --- a/libs/signalrcore/transport/base_transport.py +++ b/libs/signalrcore/transport/base_transport.py @@ -7,8 +7,8 @@ class BaseTransport(object): self._on_message= on_message self.logger = Helpers.get_logger() self._on_open = lambda: self.logger.info("on_connect not defined") - self._on_close = lambda: self.logger.info( - "on_disconnect not defined") + self._on_close = lambda: self.logger.info("on_disconnect not defined") + self._on_reconnect = lambda: self.logger.info("on_reconnect not defined") def on_open_callback(self, callback): self._on_open = callback @@ -16,6 +16,9 @@ class BaseTransport(object): def on_close_callback(self, callback): self._on_close = callback + def on_reconnect_callback(self, callback): + self._on_reconnect = callback + def start(self): # pragma: no cover raise NotImplementedError() diff --git a/libs/signalrcore/transport/websockets/websocket_transport.py b/libs/signalrcore/transport/websockets/websocket_transport.py index 4c05add53..1b98c27e4 100644 --- a/libs/signalrcore/transport/websockets/websocket_transport.py +++ b/libs/signalrcore/transport/websockets/websocket_transport.py @@ -144,6 +144,12 @@ class WebsocketTransport(BaseTransport): if self._on_close is not None and callable(self._on_close): self._on_close() + def on_reconnect(self): + self.logger.debug("-- web socket reconnecting --") + self.state = ConnectionState.disconnected + if self._on_close is not None and callable(self._on_close): + self._on_close() + def on_socket_error(self, error): """ Throws error related on @@ -217,6 +223,9 @@ class WebsocketTransport(BaseTransport): raise ex def handle_reconnect(self): + if not self.reconnection_handler.reconnecting and self._on_reconnect is not None and \ + callable(self._on_reconnect): + self._on_reconnect() self.reconnection_handler.reconnecting = True try: self.stop() diff --git a/libs/version.txt b/libs/version.txt index 848a598c3..6749d13c3 100644 --- a/libs/version.txt +++ b/libs/version.txt @@ -30,7 +30,7 @@ rebulk=3.0.1 requests=2.18.4 semver=2.13.0 signalr-client=0.0.7 <-- Modified to work with Sonarr -signalrcore=0.9.2 +signalrcore=0.9.2 <-- https://github.com/mandrewcito/signalrcore/pull/60 SimpleConfigParser=0.1.0 <-- modified version: do not update!!! six=1.11.0 socketio=5.1.0