From 32d38b11e1a6c43fd0a082faf3d58d6a1661e769 Mon Sep 17 00:00:00 2001 From: Jan David Mol <mol@astron.nl> Date: Wed, 2 Dec 2020 10:07:09 +0100 Subject: [PATCH] Move reconnect functionality to separate class --- RCUSCC/RCUSCC/RCUSCC.py | 91 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/RCUSCC/RCUSCC/RCUSCC.py b/RCUSCC/RCUSCC/RCUSCC.py index 62824eb73..68a2184ac 100644 --- a/RCUSCC/RCUSCC/RCUSCC.py +++ b/RCUSCC/RCUSCC/RCUSCC.py @@ -46,7 +46,7 @@ def fault_on_opcua_error(func): except Exception as e: self.error_stream("Communication with the OPC-UA server %s:%d failed. Reconnecting. Trace: %s" % (self.OPC_Server_Name, self.OPC_Server_Port, traceback.format_exc())) self.set_state(DevState.FAULT) - self._reconnect_opcua() + self.opcua_connector.reconnect() return None @@ -57,7 +57,7 @@ __all__ = ["RCUSCC", "main"] class BackgroundConnector(Thread): """ - Run a function in the background, until it succeeds. + Run a connector function in the background, until it succeeds. """ def __init__(self, connect_func, try_interval=2, debug_stream=print): @@ -84,6 +84,53 @@ class BackgroundConnector(Thread): if not self.connected: time.sleep(self.try_interval) +class BackgroundReconnector(object): + """ + Keeps a connection attempt going. + """ + + def __init__(self, connect_func, disconnect_func, debug_stream=print): + self.connect_func = connect_func + self.disconnect_func = disconnect_func + self.debug_stream = debug_stream + + self._connect() + + def _connect(self): + self.connector = BackgroundConnector(self.connect_func, debug_stream=self.debug_stream) + self.connector.start() + + def reconnect(self): + """ + Connect or reconnect to the OPC-UA server. + """ + + if self.connector.connecting: + # don't try twice in parallel + return + + # reap previous instance + self.debug_stream("reaping previous connector") + self.connector.join() + + # disconnect if necessary + self.debug_stream("disconnecting (if connected)") + self.disconnect_func() + + # connect in the background + self.debug_stream("connecting") + self._connect() + + def wait_connected(self): + """ + Wait until a connection is established. + """ + + # wait for attempt to finish + self.connector.join() + + if not self.connector.connected: + raise Exception("Could not connect to server") class RCUSCC(Device): """ @@ -205,39 +252,6 @@ class RCUSCC(Device): return DummyNode() - def _reconnect_opcua(self): - """ - Connect or reconnect to the OPC-UA server. - """ - - if self.opcua_connector: - if self.opcua_connector.connecting: - # don't try twice in parallel - return - - # reap previous instance - self.debug_stream("reaping previous connector") - self.opcua_connector.join() - - self.debug_stream("disconnecting (if connected)") - self._disconnect() - self.debug_stream("connecting") - self.opcua_connector = BackgroundConnector(self._init_opcua) - self.opcua_connector.start() - - def _wait_opcua_connect(self): - """ - Wait until an OPC-UA connection is established. - """ - - if not self.opcua_connector: - # start connecting if not already - self._reconnect_opcua() - - self.opcua_connector.join() - - if not self.opcua_connector.connected: - raise Exception("Could not connect to OPC-UA server") def _init_opcua(self): self.debug_stream("Connecting to OPC-UA server %s:%d...", self.OPC_Server_Name, self.OPC_Server_Port) @@ -305,9 +319,6 @@ class RCUSCC(Device): # PROTECTED REGION ID(RCUSCC.init_device) ENABLED START # self.set_state(DevState.INIT) - # Thread to connect to OPC-UA in the background - self.opcua_connector = None - # Init the dict that contains attribute to OPC-UA MP/CP mappings. self.attribute_mapping = {} @@ -350,7 +361,9 @@ class RCUSCC(Device): # Set defaults to property values. try: - self._wait_opcua_connect() + # Connect to OPC-UA + self.opcua_connector = BackgroundReconnector(self._init_opcua, self._disconnect, self.debug_stream) + self.opcua_connector.wait_connected() self.set_state(DevState.ON) except Exception as e: -- GitLab