tMerge pull request #1270 from kyuupichan/if-tristate - electrum - Electrum Bitcoin wallet (HTM) git clone https://git.parazyd.org/electrum (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules --- (DIR) commit 832369d7c444270bbd562798a438e6c460c1c85c (DIR) parent 0938299e9bf858817d3c391ebcdca3d48d5dd3d4 (HTM) 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: M lib/interface.py | 32 +++++++++++++++++++------------ M lib/network.py | 9 +++++---- 2 files changed, 25 insertions(+), 16 deletions(-) --- (DIR) diff --git a/lib/interface.py b/lib/interface.py t@@ -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): t@@ -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 t@@ -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 t@@ -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) t@@ -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)) (DIR) diff --git a/lib/network.py b/lib/network.py t@@ -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: t@@ -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'''