mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-12-23 11:12:47 +01:00
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):
|
||||
_instances = []
|
||||
_selecting = [False] # We want it to be mutable.
|
||||
def __init__(self, irc):
|
||||
self._instances.append(self)
|
||||
self.irc = irc
|
||||
drivers.IrcDriver.__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.
|
||||
if e.args[0] != 11 or self.eagains > 120:
|
||||
drivers.log.disconnect(self.currentServer, e)
|
||||
if self in self._instances:
|
||||
self._instances.remove(self)
|
||||
try:
|
||||
self.conn.close()
|
||||
except:
|
||||
@ -129,6 +134,32 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||
if self.zombie and not self.outbuffer:
|
||||
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):
|
||||
now = time.time()
|
||||
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())
|
||||
return
|
||||
self._sendIfMsgs()
|
||||
self._select()
|
||||
|
||||
def _read(self):
|
||||
"""Called by _select() when we can read data."""
|
||||
try:
|
||||
self.inbuffer += self.conn.recv(1024)
|
||||
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
|
||||
if self.connected:
|
||||
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.connected = False
|
||||
if reset:
|
||||
@ -225,6 +263,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||
drivers.log.connectError(self.currentServer, e)
|
||||
self.scheduleReconnect()
|
||||
return
|
||||
self._instances.append(self)
|
||||
|
||||
def _checkAndWriteOrReconnect(self):
|
||||
self.writeCheckTime = None
|
||||
@ -250,6 +289,8 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||
self.nextReconnectTime = when
|
||||
|
||||
def die(self):
|
||||
if self in self._instances:
|
||||
self._instances.remove(self)
|
||||
self.zombie = True
|
||||
if self.nextReconnectTime is not None:
|
||||
self.nextReconnectTime = None
|
||||
@ -259,6 +300,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin):
|
||||
|
||||
def _reallyDie(self):
|
||||
if self.conn is not None:
|
||||
self.conn.shutdown(socket.SHUT_RDWR)
|
||||
self.conn.close()
|
||||
drivers.IrcDriver.die(self)
|
||||
# self.irc.die() Kill off the ircs yourself, jerk!
|
||||
|
Loading…
Reference in New Issue
Block a user