Merge pull request #1270 from kyuupichan/if-tristate
Make interface status tri-state.
This commit is contained in:
commit
832369d7c4
|
@ -48,6 +48,9 @@ def Interface(server, response_queue, config = None):
|
||||||
else:
|
else:
|
||||||
raise Exception('Unknown protocol: %s'%protocol)
|
raise Exception('Unknown protocol: %s'%protocol)
|
||||||
|
|
||||||
|
# Connection status
|
||||||
|
CS_OPENING, CS_CONNECTED, CS_FAILED = range(3)
|
||||||
|
|
||||||
class TcpInterface(threading.Thread):
|
class TcpInterface(threading.Thread):
|
||||||
|
|
||||||
def __init__(self, server, response_queue, config = None):
|
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
|
# Set by stop(); no more data is exchanged and the thread exits after gracefully
|
||||||
# closing the socket
|
# closing the socket
|
||||||
self.disconnect = False
|
self.disconnect = False
|
||||||
# Initially True to avoid a race; set to False on failure to create a socket or when
|
self._status = CS_OPENING
|
||||||
# it is closed
|
self.needs_shutdown = True
|
||||||
self.connected = True
|
|
||||||
self.debug = False # dump network messages. can be changed at runtime using the console
|
self.debug = False # dump network messages. can be changed at runtime using the console
|
||||||
self.message_id = 0
|
self.message_id = 0
|
||||||
self.response_queue = response_queue
|
self.response_queue = response_queue
|
||||||
|
@ -275,9 +277,11 @@ class TcpInterface(threading.Thread):
|
||||||
self.message_id += 1
|
self.message_id += 1
|
||||||
|
|
||||||
def is_connected(self):
|
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):
|
def stop(self):
|
||||||
|
if not self.disconnect:
|
||||||
self.disconnect = True
|
self.disconnect = True
|
||||||
self.print_error("disconnecting")
|
self.print_error("disconnecting")
|
||||||
|
|
||||||
|
@ -299,7 +303,8 @@ class TcpInterface(threading.Thread):
|
||||||
return
|
return
|
||||||
# If remote side closed the socket, SocketPipe closes our socket and returns None
|
# If remote side closed the socket, SocketPipe closes our socket and returns None
|
||||||
if response is 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")
|
self.print_error("connection closed remotely")
|
||||||
else:
|
else:
|
||||||
self.process_response(response)
|
self.process_response(response)
|
||||||
|
@ -310,22 +315,25 @@ class TcpInterface(threading.Thread):
|
||||||
self.pipe = util.SocketPipe(s)
|
self.pipe = util.SocketPipe(s)
|
||||||
s.settimeout(0.1)
|
s.settimeout(0.1)
|
||||||
self.print_error("connected")
|
self.print_error("connected")
|
||||||
|
self._status = CS_CONNECTED
|
||||||
# Indicate to parent that we've connected
|
# Indicate to parent that we've connected
|
||||||
self.change_status()
|
self.notify_status()
|
||||||
while self.is_connected():
|
while self.is_connected():
|
||||||
self.maybe_ping()
|
self.maybe_ping()
|
||||||
self.send_requests()
|
self.send_requests()
|
||||||
self.get_and_process_response()
|
self.get_and_process_response()
|
||||||
if self.connected: # Don't shutdown() a closed socket
|
if self.needs_shutdown:
|
||||||
s.shutdown(socket.SHUT_RDWR)
|
s.shutdown(socket.SHUT_RDWR)
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
# Also for the s is None case
|
# Also for the s is None case
|
||||||
self.connected = False
|
self._status = CS_FAILED
|
||||||
# Indicate to parent that the connection is now down
|
# 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))
|
self.response_queue.put((self, None))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,8 @@ class Network(util.DaemonThread):
|
||||||
return self.config.get('auto_connect', False)
|
return self.config.get('auto_connect', False)
|
||||||
|
|
||||||
def get_interfaces(self):
|
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):
|
def get_servers(self):
|
||||||
if self.irc_servers:
|
if self.irc_servers:
|
||||||
|
@ -339,9 +340,9 @@ class Network(util.DaemonThread):
|
||||||
self.switch_lagging_interface()
|
self.switch_lagging_interface()
|
||||||
|
|
||||||
def switch_to_random_interface(self):
|
def switch_to_random_interface(self):
|
||||||
if self.interfaces:
|
servers = self.get_interfaces() # Those in connected state
|
||||||
server = random.choice(self.interfaces.keys())
|
if servers:
|
||||||
self.switch_to_interface(server)
|
self.switch_to_interface(random.choice(servers))
|
||||||
|
|
||||||
def switch_lagging_interface(self, suggestion = None):
|
def switch_lagging_interface(self, suggestion = None):
|
||||||
'''If auto_connect and lagging, switch interface'''
|
'''If auto_connect and lagging, switch interface'''
|
||||||
|
|
Loading…
Reference in New Issue