mirror of https://github.com/Mikaela/Limnoria.git
Socket: Use select.select() instead of checking sockets one by one. Closes GH-431. Closes GH-420.
This commit is contained in:
parent
7d22d3dc36
commit
8cf094a628
|
@ -56,7 +56,10 @@ except:
|
||||||
|
|
||||||
|
|
||||||
class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
|
_instances = []
|
||||||
|
_selecting = [False] # We want it to be mutable.
|
||||||
def __init__(self, irc):
|
def __init__(self, irc):
|
||||||
|
self._instances.append(self)
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
drivers.IrcDriver.__init__(self, irc)
|
drivers.IrcDriver.__init__(self, irc)
|
||||||
drivers.ServersMixin.__init__(self, irc)
|
drivers.ServersMixin.__init__(self, irc)
|
||||||
|
@ -99,6 +102,8 @@ 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)
|
||||||
|
if self in self._instances:
|
||||||
|
self._instances.remove(self)
|
||||||
try:
|
try:
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
except:
|
except:
|
||||||
|
@ -129,6 +134,32 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
if self.zombie and not self.outbuffer:
|
if self.zombie and not self.outbuffer:
|
||||||
self._reallyDie()
|
self._reallyDie()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _select(cls):
|
||||||
|
if cls._selecting[0]:
|
||||||
|
return
|
||||||
|
print repr(map(lambda x:x.name(), cls._instances))
|
||||||
|
try:
|
||||||
|
cls._selecting[0] = True
|
||||||
|
for inst in cls._instances:
|
||||||
|
# Do not use a list comprehension here, we have to edit the list
|
||||||
|
# and not to reassign it.
|
||||||
|
if inst.conn._sock.__class__ is socket._closedsocket:
|
||||||
|
cls._instances.remove(inst)
|
||||||
|
if not cls._instances:
|
||||||
|
return
|
||||||
|
rlist, wlist, xlist = select.select([x.conn for x in cls._instances],
|
||||||
|
[], [], conf.supybot.drivers.poll())
|
||||||
|
for instance in cls._instances:
|
||||||
|
if instance.conn in rlist:
|
||||||
|
instance._read()
|
||||||
|
finally:
|
||||||
|
cls._selecting[0] = False
|
||||||
|
for instance in cls._instances:
|
||||||
|
if not instance.irc.zombie:
|
||||||
|
instance._sendIfMsgs()
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if self.nextReconnectTime is not None and now > self.nextReconnectTime:
|
if self.nextReconnectTime is not None and now > self.nextReconnectTime:
|
||||||
|
@ -141,6 +172,10 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
time.sleep(conf.supybot.drivers.poll())
|
time.sleep(conf.supybot.drivers.poll())
|
||||||
return
|
return
|
||||||
self._sendIfMsgs()
|
self._sendIfMsgs()
|
||||||
|
self._select()
|
||||||
|
|
||||||
|
def _read(self):
|
||||||
|
"""Called by _select() when we can read data."""
|
||||||
try:
|
try:
|
||||||
self.inbuffer += self.conn.recv(1024)
|
self.inbuffer += self.conn.recv(1024)
|
||||||
self.eagains = 0 # If we successfully recv'ed, we can reset this.
|
self.eagains = 0 # If we successfully recv'ed, we can reset this.
|
||||||
|
@ -173,6 +208,9 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
self.nextReconnectTime = None
|
self.nextReconnectTime = None
|
||||||
if self.connected:
|
if self.connected:
|
||||||
drivers.log.reconnect(self.irc.network)
|
drivers.log.reconnect(self.irc.network)
|
||||||
|
if self in self._instances:
|
||||||
|
self._instances.remove(self)
|
||||||
|
self.conn.shutdown(socket.SHUT_RDWR)
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
self.connected = False
|
self.connected = False
|
||||||
if reset:
|
if reset:
|
||||||
|
@ -225,6 +263,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
drivers.log.connectError(self.currentServer, e)
|
drivers.log.connectError(self.currentServer, e)
|
||||||
self.scheduleReconnect()
|
self.scheduleReconnect()
|
||||||
return
|
return
|
||||||
|
self._instances.append(self)
|
||||||
|
|
||||||
def _checkAndWriteOrReconnect(self):
|
def _checkAndWriteOrReconnect(self):
|
||||||
self.writeCheckTime = None
|
self.writeCheckTime = None
|
||||||
|
@ -250,6 +289,8 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
self.nextReconnectTime = when
|
self.nextReconnectTime = when
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
|
if self in self._instances:
|
||||||
|
self._instances.remove(self)
|
||||||
self.zombie = True
|
self.zombie = True
|
||||||
if self.nextReconnectTime is not None:
|
if self.nextReconnectTime is not None:
|
||||||
self.nextReconnectTime = None
|
self.nextReconnectTime = None
|
||||||
|
@ -259,6 +300,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||||
|
|
||||||
def _reallyDie(self):
|
def _reallyDie(self):
|
||||||
if self.conn is not None:
|
if self.conn is not None:
|
||||||
|
self.conn.shutdown(socket.SHUT_RDWR)
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
drivers.IrcDriver.die(self)
|
drivers.IrcDriver.die(self)
|
||||||
# self.irc.die() Kill off the ircs yourself, jerk!
|
# self.irc.die() Kill off the ircs yourself, jerk!
|
||||||
|
|
Loading…
Reference in New Issue