commit 832369d7c444270bbd562798a438e6c460c1c85c
parent 0938299e9bf858817d3c391ebcdca3d48d5dd3d4
Author: ThomasV <electrumdev@gmail.com>
Date: Mon, 1 Jun 2015 13:09:40 +0200
Merge pull request #1270 from kyuupichan/if-tristate
Make interface status tri-state.
Diffstat:
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/lib/interface.py b/lib/interface.py
@@ -48,6 +48,9 @@ def Interface(server, response_queue, config = None):
else:
raise Exception('Unknown protocol: %s'%protocol)
+# Connection status
+CS_OPENING, CS_CONNECTED, CS_FAILED = range(3)
+
class TcpInterface(threading.Thread):
def __init__(self, server, response_queue, config = None):
@@ -57,9 +60,8 @@ class TcpInterface(threading.Thread):
# Set by stop(); no more data is exchanged and the thread exits after gracefully
# closing the socket
self.disconnect = False
- # Initially True to avoid a race; set to False on failure to create a socket or when
- # it is closed
- self.connected = True
+ self._status = CS_OPENING
+ self.needs_shutdown = True
self.debug = False # dump network messages. can be changed at runtime using the console
self.message_id = 0
self.response_queue = response_queue
@@ -275,11 +277,13 @@ class TcpInterface(threading.Thread):
self.message_id += 1
def is_connected(self):
- return self.connected and not self.disconnect
+ '''True if status is connected'''
+ return self._status == CS_CONNECTED and not self.disconnect
def stop(self):
- self.disconnect = True
- self.print_error("disconnecting")
+ if not self.disconnect:
+ self.disconnect = True
+ self.print_error("disconnecting")
def maybe_ping(self):
# ping the server with server.version
@@ -299,7 +303,8 @@ class TcpInterface(threading.Thread):
return
# If remote side closed the socket, SocketPipe closes our socket and returns None
if response is None:
- self.connected = False # Don't re-close the socket
+ self.needs_shutdown = False # Don't re-close the socket
+ self.disconnect = True
self.print_error("connection closed remotely")
else:
self.process_response(response)
@@ -310,22 +315,25 @@ class TcpInterface(threading.Thread):
self.pipe = util.SocketPipe(s)
s.settimeout(0.1)
self.print_error("connected")
+ self._status = CS_CONNECTED
# Indicate to parent that we've connected
- self.change_status()
+ self.notify_status()
while self.is_connected():
self.maybe_ping()
self.send_requests()
self.get_and_process_response()
- if self.connected: # Don't shutdown() a closed socket
+ if self.needs_shutdown:
s.shutdown(socket.SHUT_RDWR)
s.close()
# Also for the s is None case
- self.connected = False
+ self._status = CS_FAILED
# Indicate to parent that the connection is now down
- self.change_status()
+ self.notify_status()
- def change_status(self):
+ def notify_status(self):
+ '''Notify owner that we have just connected or just failed the connection.
+ Owner determines which through e.g. testing is_connected()'''
self.response_queue.put((self, None))
diff --git a/lib/network.py b/lib/network.py
@@ -259,7 +259,8 @@ class Network(util.DaemonThread):
return self.config.get('auto_connect', False)
def get_interfaces(self):
- return self.interfaces.keys()
+ '''The interfaces that are in connected state'''
+ return [s for s, i in self.interfaces.items() if i.is_connected()]
def get_servers(self):
if self.irc_servers:
@@ -339,9 +340,9 @@ class Network(util.DaemonThread):
self.switch_lagging_interface()
def switch_to_random_interface(self):
- if self.interfaces:
- server = random.choice(self.interfaces.keys())
- self.switch_to_interface(server)
+ servers = self.get_interfaces() # Those in connected state
+ if servers:
+ self.switch_to_interface(random.choice(servers))
def switch_lagging_interface(self, suggestion = None):
'''If auto_connect and lagging, switch interface'''