mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-30 14:59:34 +01:00
Refactored the Socket driver, hopefully to resolve the currently outstanding bugs (#1156765 and #1097217) with it.
This commit is contained in:
parent
6986bbad16
commit
8730832e69
@ -45,9 +45,6 @@ import supybot.drivers as drivers
|
|||||||
import supybot.schedule as schedule
|
import supybot.schedule as schedule
|
||||||
from supybot.utils.iter import imap
|
from supybot.utils.iter import imap
|
||||||
|
|
||||||
# XXX Shouldn't the reconnect wait (at least the last one) be configurable?
|
|
||||||
reconnectWaits = [0, 60, 300]
|
|
||||||
|
|
||||||
class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
def __init__(self, irc):
|
def __init__(self, irc):
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
@ -61,20 +58,28 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.zombie = False
|
self.zombie = False
|
||||||
self.scheduled = None
|
self.scheduled = None
|
||||||
self.connected = False
|
self.connected = False
|
||||||
self.reconnectWaitsIndex = 0
|
self.resetDelay()
|
||||||
self.reconnectWaits = reconnectWaits
|
# Only connect to non-SSL servers
|
||||||
#Only connect to non-SSL servers
|
|
||||||
if self.networkGroup.get('ssl').value:
|
if self.networkGroup.get('ssl').value:
|
||||||
drivers.log.error('The Socket driver can not connect to SSL '
|
drivers.log.error('The Socket driver can not connect to SSL '
|
||||||
'servers. Try the Twisted driver instead.')
|
'servers. Try the Twisted driver instead.')
|
||||||
else:
|
else:
|
||||||
self.connect()
|
self.connect()
|
||||||
|
|
||||||
|
def getDelay(self):
|
||||||
|
ret = self.currentDelay
|
||||||
|
self.currentDelay = min(self.currentDelay * 2,
|
||||||
|
conf.supybot.drivers.maxReconnectWait())
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def resetDelay(self):
|
||||||
|
self.currentDelay = 10.0
|
||||||
|
|
||||||
def _getNextServer(self):
|
def _getNextServer(self):
|
||||||
oldServer = getattr(self, 'currentServer', None)
|
oldServer = getattr(self, 'currentServer', None)
|
||||||
server = self.__parent._getNextServer()
|
server = self.__parent._getNextServer()
|
||||||
if self.currentServer != oldServer:
|
if self.currentServer != oldServer:
|
||||||
self.reconnectWaitsIndex = 0
|
self.resetDelay()
|
||||||
return server
|
return server
|
||||||
|
|
||||||
def _handleSocketError(self, e):
|
def _handleSocketError(self, e):
|
||||||
@ -82,7 +87,7 @@ 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 and self.eagains > 120:
|
if e.args[0] != 11 and self.eagains > 120:
|
||||||
drivers.log.disconnect(self.currentServer, e)
|
drivers.log.disconnect(self.currentServer, e)
|
||||||
self.reconnect(wait=True)
|
self.scheduleReconnect()
|
||||||
else:
|
else:
|
||||||
log.debug('Got EAGAIN, current count: %s.', self.eagains)
|
log.debug('Got EAGAIN, current count: %s.', self.eagains)
|
||||||
self.eagains += 1
|
self.eagains += 1
|
||||||
@ -113,7 +118,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self._sendIfMsgs()
|
self._sendIfMsgs()
|
||||||
try:
|
try:
|
||||||
self.inbuffer += self.conn.recv(1024)
|
self.inbuffer += self.conn.recv(1024)
|
||||||
self.eagains = 0
|
self.eagains = 0 # If we successfully recv'ed, we can reset this.
|
||||||
lines = self.inbuffer.split('\n')
|
lines = self.inbuffer.split('\n')
|
||||||
self.inbuffer = lines.pop()
|
self.inbuffer = lines.pop()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
@ -131,8 +136,8 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
def connect(self, **kwargs):
|
def connect(self, **kwargs):
|
||||||
self.reconnect(reset=False, **kwargs)
|
self.reconnect(reset=False, **kwargs)
|
||||||
|
|
||||||
def reconnect(self, wait=False, reset=True):
|
def reconnect(self, reset=True):
|
||||||
self.scheduled = False
|
self.scheduled = 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()
|
||||||
@ -142,9 +147,6 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.irc.reset()
|
self.irc.reset()
|
||||||
else:
|
else:
|
||||||
drivers.log.debug('Not resetting %s.', self.irc)
|
drivers.log.debug('Not resetting %s.', self.irc)
|
||||||
if wait:
|
|
||||||
self._scheduleReconnect()
|
|
||||||
return
|
|
||||||
server = self._getNextServer()
|
server = self._getNextServer()
|
||||||
drivers.log.connect(self.currentServer)
|
drivers.log.connect(self.currentServer)
|
||||||
try:
|
try:
|
||||||
@ -153,18 +155,16 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
self.conn.bind((vhost, 0))
|
self.conn.bind((vhost, 0))
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
drivers.log.connectError(self.currentServer, e)
|
drivers.log.connectError(self.currentServer, e)
|
||||||
if self.reconnectWaitsIndex < len(self.reconnectWaits)-1:
|
self.scheduleReconnect()
|
||||||
self.reconnectWaitsIndex += 1
|
|
||||||
self.reconnect(wait=True)
|
|
||||||
return
|
return
|
||||||
# We allow more time for the connect here, since it might take longer.
|
# We allow more time for the connect here, since it might take longer.
|
||||||
# At least 10 seconds.
|
# At least 10 seconds.
|
||||||
self.conn.settimeout(max(10, conf.supybot.drivers.poll()*10))
|
self.conn.settimeout(max(10, conf.supybot.drivers.poll()*10))
|
||||||
if self.reconnectWaitsIndex < len(self.reconnectWaits)-1:
|
|
||||||
self.reconnectWaitsIndex += 1
|
|
||||||
try:
|
try:
|
||||||
self.conn.connect(server)
|
self.conn.connect(server)
|
||||||
self.conn.settimeout(conf.supybot.drivers.poll())
|
self.conn.settimeout(conf.supybot.drivers.poll())
|
||||||
|
self.connected = True
|
||||||
|
self.resetDelay()
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if e.args[0] == 115:
|
if e.args[0] == 115:
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@ -175,10 +175,8 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
schedule.addEvent(self._checkAndWriteOrReconnect, when)
|
schedule.addEvent(self._checkAndWriteOrReconnect, when)
|
||||||
else:
|
else:
|
||||||
drivers.log.connectError(self.currentServer, e)
|
drivers.log.connectError(self.currentServer, e)
|
||||||
self.reconnect(wait=True)
|
self.scheduleReconnect()
|
||||||
return
|
return
|
||||||
self.connected = True
|
|
||||||
self.reconnectWaitPeriodsIndex = 0
|
|
||||||
|
|
||||||
def _checkAndWriteOrReconnect(self):
|
def _checkAndWriteOrReconnect(self):
|
||||||
drivers.log.debug('Checking whether we are connected.')
|
drivers.log.debug('Checking whether we are connected.')
|
||||||
@ -186,15 +184,21 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
|||||||
if w:
|
if w:
|
||||||
drivers.log.debug('Socket is writable, it might be connected.')
|
drivers.log.debug('Socket is writable, it might be connected.')
|
||||||
self.connected = True
|
self.connected = True
|
||||||
self.reconnectWaitPeriodsIndex = 0
|
self.resetDelay()
|
||||||
else:
|
else:
|
||||||
drivers.log.connectError(self.currentServer, 'Timed out')
|
drivers.log.connectError(self.currentServer, 'Timed out')
|
||||||
self.reconnect()
|
self.reconnect()
|
||||||
|
|
||||||
def _scheduleReconnect(self):
|
def scheduleReconnect(self):
|
||||||
when = time.time() + self.reconnectWaits[self.reconnectWaitsIndex]
|
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:
|
||||||
|
drivers.log.error('Scheduling a second reconnect when one is '
|
||||||
|
'already scheduled. This is a bug; please '
|
||||||
|
'report it, with an explanation of what caused '
|
||||||
|
'this to happen.')
|
||||||
|
schedule.removeEvent(self.scheduled)
|
||||||
self.scheduled = schedule.addEvent(self.reconnect, when)
|
self.scheduled = schedule.addEvent(self.reconnect, when)
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user