3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-24 03:29:28 +01:00

classes: IRC object disconnect tweaks (really fixes #152)

- disconnect() was missing a socket.shutdown() cause, as socket.close() does NOT cause connections to close immediately! https://docs.python.org/3/library/socket.html#socket.socket.close
- Merge _disconnect() and disconnect(), the latter was just a wrapper with little use
This commit is contained in:
James Lu 2016-01-09 19:38:27 -08:00
parent f2efaf9437
commit f70ca54ae4
2 changed files with 28 additions and 18 deletions

View File

@ -56,7 +56,9 @@ class Irc():
# HACK: Don't thread if we're running tests. # HACK: Don't thread if we're running tests.
self.connect() self.connect()
else: else:
self.connection_thread = threading.Thread(target = self.connect) self.connection_thread = threading.Thread(target=self.connect,
name="Listener for %s" %
self.name)
self.connection_thread.start() self.connection_thread.start()
self.pingTimer = None self.pingTimer = None
@ -225,9 +227,10 @@ class Irc():
# exception, meaning we've disconnected! # exception, meaning we've disconnected!
log.warning('(%s) Disconnected from IRC: %s: %s', log.warning('(%s) Disconnected from IRC: %s: %s',
self.name, type(e).__name__, str(e)) self.name, type(e).__name__, str(e))
self.disconnect()
# The run() loop above was broken, meaning we've disconnected. # Internal hook signifying that a network has disconnected.
self._disconnect() self.callHooks([None, 'PYLINK_DISCONNECT', {}])
# If autoconnect is enabled, loop back to the start. Otherwise, # If autoconnect is enabled, loop back to the start. Otherwise,
# return and stop. # return and stop.
@ -240,21 +243,25 @@ class Irc():
log.info('(%s) Stopping connect loop (autoconnect value %r is < 1).', self.name, autoconnect) log.info('(%s) Stopping connect loop (autoconnect value %r is < 1).', self.name, autoconnect)
return return
def _disconnect(self):
"""Handle disconnects from the remote server."""
log.debug('(%s) Canceling pingTimer at %s due to _disconnect() call', self.name, time.time())
self.connected.clear()
try:
self.socket.close()
self.pingTimer.cancel()
except: # Socket timed out during creation; ignore
pass
# Internal hook signifying that a network has disconnected.
self.callHooks([None, 'PYLINK_DISCONNECT', {}])
def disconnect(self): def disconnect(self):
"""Closes the IRC connection.""" """Handle disconnects from the remote server."""
self.aborted.set() # This will cause run() to abort.
log.debug('(%s) _disconnect: Clearing self.connected state.', self.name)
self.connected.clear()
log.debug('(%s) _disconnect: Setting self.aborted to True.', self.name)
self.aborted.set()
try:
log.debug('(%s) _disconnect: Shutting down and closing socket.', self.name)
self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()
except: # Socket timed out during creation; ignore
log.exception('(%s) _disconnect: Failed to close/shutdown socket.', self.name)
if self.pingTimer:
log.debug('(%s) Canceling pingTimer at %s due to disconnect() call', self.name, time.time())
self.pingTimer.cancel()
def run(self): def run(self):
"""Main IRC loop which listens for messages.""" """Main IRC loop which listens for messages."""
@ -353,9 +360,12 @@ class Irc():
def schedulePing(self): def schedulePing(self):
"""Schedules periodic pings in a loop.""" """Schedules periodic pings in a loop."""
self.proto.pingServer() self.proto.pingServer()
self.pingTimer = threading.Timer(self.pingfreq, self.schedulePing) self.pingTimer = threading.Timer(self.pingfreq, self.schedulePing)
self.pingTimer.daemon = True self.pingTimer.daemon = True
self.pingTimer.name = 'Ping timer loop for %s' % self.name
self.pingTimer.start() self.pingTimer.start()
log.debug('(%s) Ping scheduled at %s', self.name, time.time()) log.debug('(%s) Ping scheduled at %s', self.name, time.time())
def spawnMain(self): def spawnMain(self):

View File

@ -177,7 +177,7 @@ def shutdown(irc, source, args):
for ircobj in world.networkobjects.values(): for ircobj in world.networkobjects.values():
# Disable auto-connect first by setting the time to negative. # Disable auto-connect first by setting the time to negative.
ircobj.serverdata['autoconnect'] = -1 ircobj.serverdata['autoconnect'] = -1
ircobj.aborted.set() ircobj.disconnect(callhook=False)
def load(irc, source, args): def load(irc, source, args):
"""<plugin name>. """<plugin name>.