mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-28 05:39:24 +01:00
Socket: Ensure driver is flagged as disconnected after a socket error.
Users were occasionally hitting a situation where the socket had errored,
causing a reconnect, but the socket wasn't closed nor the driver marked as
disconnected. This resulted in run() continuing to try and use the driver,
which would cause another error, schedule another reconnect, log an error, ad
infinitum.
Closes: Sf#2965530
Signed-off-by: James Vega <jamessan@users.sourceforge.net>
(cherry picked from commit a278d17f2b
)
Signed-off-by: Daniel Folkinshteyn <nanotube@users.sourceforge.net>
This commit is contained in:
parent
bc8457dc90
commit
108f7f2f86
@ -1,5 +1,6 @@
|
|||||||
###
|
###
|
||||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||||
|
# Copyright (c) 2010, James Vega
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -56,8 +57,9 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.inbuffer = ''
|
self.inbuffer = ''
|
||||||
self.outbuffer = ''
|
self.outbuffer = ''
|
||||||
self.zombie = False
|
self.zombie = False
|
||||||
self.scheduled = None
|
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
self.writeCheckTime = None
|
||||||
|
self.nextReconnectTime = None
|
||||||
self.resetDelay()
|
self.resetDelay()
|
||||||
# Only connect to non-SSL servers
|
# Only connect to non-SSL servers
|
||||||
if self.networkGroup.get('ssl').value:
|
if self.networkGroup.get('ssl').value:
|
||||||
@ -87,6 +89,11 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
# hasn't finished yet. We'll keep track of how many we get.
|
# hasn't finished yet. We'll keep track of how many we get.
|
||||||
if e.args[0] != 11 or self.eagains > 120:
|
if e.args[0] != 11 or self.eagains > 120:
|
||||||
drivers.log.disconnect(self.currentServer, e)
|
drivers.log.disconnect(self.currentServer, e)
|
||||||
|
try:
|
||||||
|
self.conn.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.connected = False
|
||||||
self.scheduleReconnect()
|
self.scheduleReconnect()
|
||||||
else:
|
else:
|
||||||
log.debug('Got EAGAIN, current count: %s.', self.eagains)
|
log.debug('Got EAGAIN, current count: %s.', self.eagains)
|
||||||
@ -110,6 +117,11 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self._reallyDie()
|
self._reallyDie()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
now = time.time()
|
||||||
|
if self.nextReconnectTime is not None and now > self.nextReconnectTime:
|
||||||
|
self.reconnect()
|
||||||
|
elif self.writeCheckTime is not None and now > self.writeCheckTime:
|
||||||
|
self._checkAndWriteOrReconnect()
|
||||||
if not self.connected:
|
if not self.connected:
|
||||||
# We sleep here because otherwise, if we're the only driver, we'll
|
# We sleep here because otherwise, if we're the only driver, we'll
|
||||||
# spin at 100% CPU while we're disconnected.
|
# spin at 100% CPU while we're disconnected.
|
||||||
@ -137,7 +149,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.reconnect(reset=False, **kwargs)
|
self.reconnect(reset=False, **kwargs)
|
||||||
|
|
||||||
def reconnect(self, reset=True):
|
def reconnect(self, reset=True):
|
||||||
self.scheduled = None
|
self.nextReconnectTime = None
|
||||||
if self.connected:
|
if self.connected:
|
||||||
drivers.log.reconnect(self.irc.network)
|
drivers.log.reconnect(self.irc.network)
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
@ -172,13 +184,14 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
whenS = log.timestamp(when)
|
whenS = log.timestamp(when)
|
||||||
drivers.log.debug('Connection in progress, scheduling '
|
drivers.log.debug('Connection in progress, scheduling '
|
||||||
'connectedness check for %s', whenS)
|
'connectedness check for %s', whenS)
|
||||||
schedule.addEvent(self._checkAndWriteOrReconnect, when)
|
self.writeCheckTime = when
|
||||||
else:
|
else:
|
||||||
drivers.log.connectError(self.currentServer, e)
|
drivers.log.connectError(self.currentServer, e)
|
||||||
self.scheduleReconnect()
|
self.scheduleReconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
def _checkAndWriteOrReconnect(self):
|
def _checkAndWriteOrReconnect(self):
|
||||||
|
self.writeCheckTime = None
|
||||||
drivers.log.debug('Checking whether we are connected.')
|
drivers.log.debug('Checking whether we are connected.')
|
||||||
(_, w, _) = select.select([], [self.conn], [], 0)
|
(_, w, _) = select.select([], [self.conn], [], 0)
|
||||||
if w:
|
if w:
|
||||||
@ -193,18 +206,19 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
when = time.time() + self.getDelay()
|
when = time.time() + self.getDelay()
|
||||||
if not world.dying:
|
if not world.dying:
|
||||||
drivers.log.reconnect(self.irc.network, when)
|
drivers.log.reconnect(self.irc.network, when)
|
||||||
if self.scheduled:
|
if self.nextReconnectTime:
|
||||||
drivers.log.error('Scheduling a second reconnect when one is '
|
drivers.log.error('Updating next reconnect time when one is '
|
||||||
'already scheduled. This is a bug; please '
|
'already present. This is a bug; please '
|
||||||
'report it, with an explanation of what caused '
|
'report it, with an explanation of what caused '
|
||||||
'this to happen.')
|
'this to happen.')
|
||||||
schedule.removeEvent(self.scheduled)
|
self.nextReconnectTime = when
|
||||||
self.scheduled = schedule.addEvent(self.reconnect, when)
|
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
self.zombie = True
|
self.zombie = True
|
||||||
if self.scheduled:
|
if self.nextReconnectTime is not None:
|
||||||
schedule.removeEvent(self.scheduled)
|
self.nextReconnectTime = None
|
||||||
|
if self.writeCheckTime is not None:
|
||||||
|
self.writeCheckTime = None
|
||||||
drivers.log.die(self.irc)
|
drivers.log.die(self.irc)
|
||||||
|
|
||||||
def _reallyDie(self):
|
def _reallyDie(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user