Improved shutdown handling for local shared instances

This commit is contained in:
Mark Qvist 2021-09-24 16:42:31 +02:00
parent 3d4ac0126b
commit 7e9d608530
3 changed files with 50 additions and 3 deletions

View File

@ -36,6 +36,8 @@ class LocalClientInterface(Interface):
self.target_port = None
self.socket = connected_socket
self.is_connected_to_shared_instance = False
elif target_port != None:
self.receives = True
self.target_ip = "127.0.0.1"
@ -116,6 +118,25 @@ class LocalClientInterface(Interface):
RNS.log("Tearing down "+str(self), RNS.LOG_ERROR)
self.teardown()
def detach(self):
if self.socket != None:
if hasattr(self.socket, "close"):
if callable(self.socket.close):
RNS.log("Detaching "+str(self), RNS.LOG_DEBUG)
self.detached = True
try:
self.socket.shutdown(socket.SHUT_RDWR)
except Exception as e:
RNS.log("Error while shutting down socket for "+str(self)+": "+str(e))
try:
self.socket.close()
except Exception as e:
RNS.log("Error while closing socket for "+str(self)+": "+str(e))
self.socket = None
def teardown(self, nowarning=False):
self.online = False
self.OUT = False
@ -132,6 +153,15 @@ class LocalClientInterface(Interface):
if RNS.Reticulum.panic_on_interface_error:
RNS.panic()
if self.is_connected_to_shared_instance:
# TODO: Maybe add automatic recovery here.
# Needs thinking through, since user needs
# to now that all connectivity has been cut
# while service is recovering. Better for
# now to take down entire stack.
RNS.log("Lost connection to local shared RNS instance. Exiting now.", RNS.LOG_CRITICAL)
RNS.panic()
def __str__(self):
return "LocalInterface["+str(self.target_port)+"]"
@ -158,6 +188,8 @@ class LocalServerInterface(Interface):
self.is_local_shared_instance = True
address = (self.bind_ip, self.bind_port)
ThreadingTCPServer.allow_reuse_address = True
self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection))
thread = threading.Thread(target=self.server.serve_forever)

View File

@ -45,6 +45,7 @@ class TCPClientInterface(Interface):
self.owner = owner
self.writing = False
self.online = False
self.detached = False
if max_reconnect_tries == None:
self.max_reconnect_tries = TCPClientInterface.RECONNECT_MAX_TRIES
@ -101,8 +102,18 @@ class TCPClientInterface(Interface):
if hasattr(self.socket, "close"):
if callable(self.socket.close):
RNS.log("Detaching "+str(self), RNS.LOG_DEBUG)
self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()
self.detached = True
try:
self.socket.shutdown(socket.SHUT_RDWR)
except Exception as e:
RNS.log("Error while shutting down socket for "+str(self)+": "+str(e))
try:
self.socket.close()
except Exception as e:
RNS.log("Error while closing socket for "+str(self)+": "+str(e))
self.socket = None
def connect(self, initial=False):
@ -216,7 +227,7 @@ class TCPClientInterface(Interface):
data_buffer = data_buffer+bytes([byte])
else:
self.online = False
if self.initiator:
if self.initiator and not self.detached:
RNS.log("TCP socket for "+str(self)+" was closed, attempting to reconnect...", RNS.LOG_WARNING)
self.reconnect()
else:
@ -285,6 +296,7 @@ class TCPServerInterface(Interface):
self.owner = owner
address = (self.bind_ip, self.bind_port)
ThreadingTCPServer.allow_reuse_address = True
self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection))

View File

@ -1427,6 +1427,9 @@ class Transport:
for interface in Transport.interfaces:
interface.detach()
for interface in Transport.local_client_interfaces:
interface.detach()
@staticmethod
def exit_handler():