mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-30 14:14:37 +01:00
Updated to allow multiple servers.
This commit is contained in:
parent
544bfa35da
commit
2336af5525
5
RELNOTES
5
RELNOTES
@ -9,12 +9,13 @@ configuration variable won't work. To fix this, add these lines to
|
|||||||
your configuration:
|
your configuration:
|
||||||
|
|
||||||
supybot.networks.default: <network>
|
supybot.networks.default: <network>
|
||||||
supybot.networks.<network>.server: <server>
|
supybot.networks.<network>.servers: <server>
|
||||||
supybot.networks.<network>.password: <password>
|
supybot.networks.<network>.password: <password>
|
||||||
|
|
||||||
Where <network> is the name of the network you're connecting to,
|
Where <network> is the name of the network you're connecting to,
|
||||||
<server> is the old supybot.server, and <password> is the old
|
<server> is the old supybot.server, and <password> is the old
|
||||||
supybot.password.
|
supybot.password. Also note the "servers" rather than "server": we
|
||||||
|
now allow the configuration of multiple servers per network.
|
||||||
|
|
||||||
Since we support multiple networks and multiple servers now, the
|
Since we support multiple networks and multiple servers now, the
|
||||||
--server option has been removed from scripts/supybot, as has the
|
--server option has been removed from scripts/supybot, as has the
|
||||||
|
@ -183,13 +183,13 @@ class Relay(callbacks.Privmsg):
|
|||||||
if serverPort is None:
|
if serverPort is None:
|
||||||
raise ValueError, '_connect requires a (server, port) if ' \
|
raise ValueError, '_connect requires a (server, port) if ' \
|
||||||
'the network is not registered.'
|
'the network is not registered.'
|
||||||
conf.registerNetwork(network, server=('%s:%s' % serverPort))
|
conf.registerNetwork(network, servers=('%s:%s' % serverPort,))
|
||||||
if makeNew:
|
if makeNew:
|
||||||
self.log.info('Creating new Irc for relaying to %s.', network)
|
self.log.info('Creating new Irc for relaying to %s.', network)
|
||||||
newIrc = irclib.Irc(network)
|
newIrc = irclib.Irc(network)
|
||||||
newIrc.state.history = realIrc.state.history
|
newIrc.state.history = realIrc.state.history
|
||||||
newIrc.callbacks = realIrc.callbacks
|
newIrc.callbacks = realIrc.callbacks
|
||||||
driver = drivers.newDriver(serverPort, newIrc)
|
driver = drivers.newDriver(newIrc)
|
||||||
else:
|
else:
|
||||||
newIrc = realIrc
|
newIrc = realIrc
|
||||||
self._addIrc(newIrc)
|
self._addIrc(newIrc)
|
||||||
|
@ -109,7 +109,6 @@ if __name__ == '__main__':
|
|||||||
# -p (profiling)
|
# -p (profiling)
|
||||||
# -O (optimizing)
|
# -O (optimizing)
|
||||||
# -n, --nick (nick)
|
# -n, --nick (nick)
|
||||||
# -s, --server (server)
|
|
||||||
# --startup (commands to run onStart)
|
# --startup (commands to run onStart)
|
||||||
# --connect (commands to run afterConnect)
|
# --connect (commands to run afterConnect)
|
||||||
# --config (configuration values)
|
# --config (configuration values)
|
||||||
@ -216,14 +215,6 @@ if __name__ == '__main__':
|
|||||||
sys.stderr.write('default when the bot starts.')
|
sys.stderr.write('default when the bot starts.')
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
server = network.server()
|
|
||||||
if ':' in server:
|
|
||||||
serverAndPort = server.split(':', 1)
|
|
||||||
serverAndPort[1] = int(serverAndPort[1])
|
|
||||||
server = tuple(serverAndPort)
|
|
||||||
else:
|
|
||||||
server = (server, 6667)
|
|
||||||
|
|
||||||
if options.optimize:
|
if options.optimize:
|
||||||
# This doesn't work anymore.
|
# This doesn't work anymore.
|
||||||
__builtins__.__debug__ = False
|
__builtins__.__debug__ = False
|
||||||
@ -262,7 +253,7 @@ if __name__ == '__main__':
|
|||||||
irc = irclib.Irc(network=defaultNetwork)
|
irc = irclib.Irc(network=defaultNetwork)
|
||||||
callback = Owner.Class()
|
callback = Owner.Class()
|
||||||
irc.addCallback(callback)
|
irc.addCallback(callback)
|
||||||
driver = drivers.newDriver(server, irc)
|
driver = drivers.newDriver(irc)
|
||||||
|
|
||||||
if options.debug:
|
if options.debug:
|
||||||
for (name, module) in sys.modules.iteritems():
|
for (name, module) in sys.modules.iteritems():
|
||||||
|
@ -63,28 +63,45 @@ class AsyncoreRunnerDriver(drivers.IrcDriver):
|
|||||||
|
|
||||||
|
|
||||||
class AsyncoreDriver(asynchat.async_chat, object):
|
class AsyncoreDriver(asynchat.async_chat, object):
|
||||||
def __init__(self, (server, port), irc):
|
def __init__(self, irc):
|
||||||
asynchat.async_chat.__init__(self)
|
asynchat.async_chat.__init__(self)
|
||||||
self.server = (server, port)
|
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
self.irc.driver = self
|
|
||||||
self.buffer = ''
|
self.buffer = ''
|
||||||
|
self.servers = ()
|
||||||
|
self.networkGroup = conf.supybot.networks.get(self.irc.network)
|
||||||
self.set_terminator('\n')
|
self.set_terminator('\n')
|
||||||
|
# XXX: Use utils.getSocket.
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
self.connect(self.server)
|
self.connect(self._getNextServer())
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
log.warning('Error connecting to %s: %s', self.server[0], e)
|
log.warning('Error connecting to %s: %s', self.currentServer, e)
|
||||||
self.reconnect(wait=True)
|
self.reconnect(wait=True)
|
||||||
|
|
||||||
|
def _getServers(self):
|
||||||
|
# We do this, rather than itertools.cycle the servers in __init__,
|
||||||
|
# because otherwise registry updates given as setValues or sets
|
||||||
|
# wouldn't be visible until a restart.
|
||||||
|
return self.networkGroup.servers()[:] # Be sure to copy!
|
||||||
|
|
||||||
|
def _getNextServer(self):
|
||||||
|
if not self.servers:
|
||||||
|
self.servers = self._getServers()
|
||||||
|
assert self.servers, 'Servers value for %s is empty.' % \
|
||||||
|
self.networkGroup.name
|
||||||
|
server = self.servers.pop(0)
|
||||||
|
self.currentServer = '%s:%s' % server
|
||||||
|
return server
|
||||||
|
|
||||||
def _scheduleReconnect(self, at=60):
|
def _scheduleReconnect(self, at=60):
|
||||||
when = time.time() + at
|
when = time.time() + at
|
||||||
if not world.dying:
|
if not world.dying:
|
||||||
whenS = log.timestamp(when)
|
whenS = log.timestamp(when)
|
||||||
log.info('Scheduling reconnect to %s at %s', self.server[0], whenS)
|
log.info('Scheduling reconnect to %s at %s',
|
||||||
|
self.currentServer, whenS)
|
||||||
def makeNewDriver():
|
def makeNewDriver():
|
||||||
self.irc.reset()
|
self.irc.reset()
|
||||||
driver = self.__class__(self.server, self.irc)
|
driver = self.__class__(self.irc)
|
||||||
schedule.addEvent(makeNewDriver, when)
|
schedule.addEvent(makeNewDriver, when)
|
||||||
|
|
||||||
def writable(self):
|
def writable(self):
|
||||||
|
33
src/conf.py
33
src/conf.py
@ -163,20 +163,41 @@ registerGlobalValue(supybot, 'user',
|
|||||||
registry.String('Supybot %s' % version, """Determines the user the bot
|
registry.String('Supybot %s' % version, """Determines the user the bot
|
||||||
sends to the server."""))
|
sends to the server."""))
|
||||||
|
|
||||||
# TODO: Make this check for validity.
|
|
||||||
registerGroup(supybot, 'networks')
|
registerGroup(supybot, 'networks')
|
||||||
registerGlobalValue(supybot.networks, 'default', registry.String('',
|
registerGlobalValue(supybot.networks, 'default',
|
||||||
"""Determines what the default network joined by the bot will be."""))
|
registry.String('', """Determines what the default network joined by the
|
||||||
|
bot will be."""))
|
||||||
|
|
||||||
def registerNetwork(name, password='', server=''):
|
class Servers(registry.SpaceSeparatedListOfStrings):
|
||||||
|
def normalize(self, s):
|
||||||
|
if ':' not in s:
|
||||||
|
s += ':6667'
|
||||||
|
return s
|
||||||
|
|
||||||
|
def convert(self, s):
|
||||||
|
s = self.normalize(s)
|
||||||
|
(server, port) = s.split(':')
|
||||||
|
port = int(port)
|
||||||
|
return (server, port)
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
L = registry.SpaceSeparatedListOfStrings.__call__(self)
|
||||||
|
return map(self.convert, L)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ' '.join(registry.SpaceSeparatedListOfStrings.__call__(self))
|
||||||
|
|
||||||
|
def registerNetwork(name, password='', servers=()):
|
||||||
name = intern(name)
|
name = intern(name)
|
||||||
network = registerGroup(supybot.networks, name)
|
network = registerGroup(supybot.networks, name)
|
||||||
registerGlobalValue(network, 'password', registry.String(password,
|
registerGlobalValue(network, 'password', registry.String(password,
|
||||||
"""Determines what password will be used on %s. Yes, we know that
|
"""Determines what password will be used on %s. Yes, we know that
|
||||||
technically passwords are server-specific and not network-specific,
|
technically passwords are server-specific and not network-specific,
|
||||||
but this is the best we can do right now.""" % name))
|
but this is the best we can do right now.""" % name))
|
||||||
registerGlobalValue(network, 'server', registry.String(server,
|
registerGlobalValue(network, 'servers', Servers(servers,
|
||||||
"""Determines what server the bot will connect to for %s.""" % name))
|
"""Determines what servers the bot will connect to for %s. Each will
|
||||||
|
be tried in order, wrapping back to the first when the cycle is
|
||||||
|
completed.""" % name))
|
||||||
return network
|
return network
|
||||||
|
|
||||||
# Let's fill our networks.
|
# Let's fill our networks.
|
||||||
|
@ -54,8 +54,6 @@ class IrcDriver(object):
|
|||||||
"""Base class for drivers."""
|
"""Base class for drivers."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
add(self.name(), self)
|
add(self.name(), self)
|
||||||
if not hasattr(self, 'irc'):
|
|
||||||
self.irc = None # This is to satisfy PyChecker.
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -113,7 +111,7 @@ def run():
|
|||||||
del _drivers[name]
|
del _drivers[name]
|
||||||
_drivers[name] = driver
|
_drivers[name] = driver
|
||||||
|
|
||||||
def newDriver(server, irc, moduleName=None):
|
def newDriver(irc, moduleName=None):
|
||||||
"""Returns a new driver for the given server using the irc given and using
|
"""Returns a new driver for the given server using the irc given and using
|
||||||
conf.supybot.driverModule to determine what driver to pick."""
|
conf.supybot.driverModule to determine what driver to pick."""
|
||||||
if moduleName is None:
|
if moduleName is None:
|
||||||
@ -128,9 +126,8 @@ def newDriver(server, irc, moduleName=None):
|
|||||||
elif not moduleName.startswith('supybot.'):
|
elif not moduleName.startswith('supybot.'):
|
||||||
moduleName = 'supybot.' + moduleName
|
moduleName = 'supybot.' + moduleName
|
||||||
driverModule = __import__(moduleName, {}, {}, ['not empty'])
|
driverModule = __import__(moduleName, {}, {}, ['not empty'])
|
||||||
log.debug('Creating new driver for %s:%s (%s)',
|
log.debug('Creating new driver for %s.', irc)
|
||||||
server[0], server[1], moduleName)
|
driver = driverModule.Driver(irc)
|
||||||
driver = driverModule.Driver(server, irc)
|
|
||||||
irc.driver = driver
|
irc.driver = driver
|
||||||
return driver
|
return driver
|
||||||
|
|
||||||
|
@ -53,30 +53,47 @@ import supybot.drivers as drivers
|
|||||||
import supybot.ircmsgs as ircmsgs
|
import supybot.ircmsgs as ircmsgs
|
||||||
import supybot.schedule as schedule
|
import supybot.schedule as schedule
|
||||||
|
|
||||||
instances = 0
|
reconnectWaits = (0, 60, 300)
|
||||||
originalPoll = conf.supybot.drivers.poll()
|
|
||||||
def resetPoll():
|
|
||||||
log.info('Resetting supybot.drivers.poll to %s', originalPoll)
|
|
||||||
conf.supybot.drivers.poll.setValue(originalPoll)
|
|
||||||
atexit.register(resetPoll)
|
|
||||||
|
|
||||||
class SocketDriver(drivers.IrcDriver):
|
class SocketDriver(drivers.IrcDriver):
|
||||||
def __init__(self, (server, port), irc, reconnectWaits=(0, 60, 300)):
|
def __init__(self, irc):
|
||||||
global instances
|
|
||||||
instances += 1
|
|
||||||
conf.supybot.drivers.poll.setValue(originalPoll / instances)
|
|
||||||
self.server = (server, port)
|
|
||||||
drivers.IrcDriver.__init__(self) # Must come after server is set.
|
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
self.irc.driver = self
|
drivers.IrcDriver.__init__(self) # Must come after setting irc.
|
||||||
|
self.networkGroup = conf.supybot.networks.get(self.irc.network)
|
||||||
|
self.servers = ()
|
||||||
|
self.eagains = 0
|
||||||
self.inbuffer = ''
|
self.inbuffer = ''
|
||||||
self.outbuffer = ''
|
self.outbuffer = ''
|
||||||
self.connected = False
|
self.connected = False
|
||||||
self.eagains = 0
|
|
||||||
self.reconnectWaitsIndex = 0
|
self.reconnectWaitsIndex = 0
|
||||||
self.reconnectWaits = reconnectWaits
|
self.reconnectWaits = reconnectWaits
|
||||||
self.connect()
|
self.connect()
|
||||||
|
|
||||||
|
def _getServers(self):
|
||||||
|
# We do this, rather than itertools.cycle the servers in __init__,
|
||||||
|
# because otherwise registry updates given as setValues or sets
|
||||||
|
# wouldn't be visible until a restart.
|
||||||
|
return self.networkGroup.servers()[:] # Be sure to copy!
|
||||||
|
|
||||||
|
def _getNextServer(self):
|
||||||
|
if not self.servers:
|
||||||
|
self.servers = self._getServers()
|
||||||
|
assert self.servers, 'Servers value for %s is empty.' % \
|
||||||
|
self.networkGroup.name
|
||||||
|
server = self.servers.pop(0)
|
||||||
|
self.currentServer = '%s:%s' % server
|
||||||
|
return server
|
||||||
|
|
||||||
|
def _handleSocketError(self, e):
|
||||||
|
# (11, 'Resource temporarily unavailable') raised if connect
|
||||||
|
# hasn't finished yet. We'll keep track of how many we get.
|
||||||
|
if e.args[0] != 11 and self.eagains > 120:
|
||||||
|
log.warning('Disconnect from %s: %s.',
|
||||||
|
self.currentServer, e.args[1])
|
||||||
|
self.reconnect(wait=True)
|
||||||
|
else:
|
||||||
|
log.debug('Got EAGAIN, current count: %s.', self.eagains)
|
||||||
|
self.eagains += 1
|
||||||
|
|
||||||
def _sendIfMsgs(self):
|
def _sendIfMsgs(self):
|
||||||
msgs = [self.irc.takeMsg()]
|
msgs = [self.irc.takeMsg()]
|
||||||
while msgs[-1] is not None:
|
while msgs[-1] is not None:
|
||||||
@ -89,15 +106,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
self.outbuffer = self.outbuffer[sent:]
|
self.outbuffer = self.outbuffer[sent:]
|
||||||
self.eagains = 0
|
self.eagains = 0
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
# (11, 'Resource temporarily unavailable') raised if connect
|
self._handleSocketError(e)
|
||||||
# hasn't finished yet.
|
|
||||||
if e.args[0] != 11 and self.eagains > 120:
|
|
||||||
server = '%s:%s' % self.server
|
|
||||||
log.warning('Disconnect from %s: %s', server, e.args[1])
|
|
||||||
self.reconnect(wait=True)
|
|
||||||
else:
|
|
||||||
log.debug('Got EAGAIN, current count: %s', self.eagains)
|
|
||||||
self.eagains += 1
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not self.connected:
|
if not self.connected:
|
||||||
@ -119,13 +128,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
pass
|
pass
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
# Same as with _sendIfMsgs.
|
self._handleSocketError(e)
|
||||||
if e.args[0] != 11 or self.eagains > 120:
|
|
||||||
log.warning('Disconnect from %s: %s', self.server, e)
|
|
||||||
self.reconnect(wait=True)
|
|
||||||
else:
|
|
||||||
log.debug('Got EAGAIN, current count: %s', self.eagains)
|
|
||||||
self.eagains += 1
|
|
||||||
return
|
return
|
||||||
self._sendIfMsgs()
|
self._sendIfMsgs()
|
||||||
|
|
||||||
@ -133,7 +136,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
self.reconnect(reset=False, **kwargs)
|
self.reconnect(reset=False, **kwargs)
|
||||||
|
|
||||||
def reconnect(self, wait=False, reset=True):
|
def reconnect(self, wait=False, reset=True):
|
||||||
server = '%s:%s' % self.server
|
server = self._getNextServer()
|
||||||
if reset:
|
if reset:
|
||||||
log.debug('Resetting %s.', self.irc)
|
log.debug('Resetting %s.', self.irc)
|
||||||
self.irc.reset()
|
self.irc.reset()
|
||||||
@ -143,16 +146,17 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
log.info('Reconnect called on driver for %s.', self.irc)
|
log.info('Reconnect called on driver for %s.', self.irc)
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
elif not wait:
|
elif not wait:
|
||||||
log.info('Connecting to %s.', server)
|
log.info('Connecting to %s.', self.currentServer)
|
||||||
self.connected = False
|
self.connected = False
|
||||||
if wait:
|
if wait:
|
||||||
log.info('Reconnect to %s waiting.', server)
|
log.info('Reconnect to %s waiting.', self.currentServer)
|
||||||
self._scheduleReconnect()
|
self._scheduleReconnect()
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.conn = utils.getSocket(self.server[0])
|
self.conn = utils.getSocket(server[0])
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
log.warning('Error connecting to %s: %s', server, e.args[1])
|
log.warning('Error connecting to %s: %s',
|
||||||
|
self.currentServer, e.args[1])
|
||||||
self.reconnect(wait=True)
|
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.
|
||||||
@ -161,7 +165,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
if self.reconnectWaitsIndex < len(self.reconnectWaits)-1:
|
if self.reconnectWaitsIndex < len(self.reconnectWaits)-1:
|
||||||
self.reconnectWaitsIndex += 1
|
self.reconnectWaitsIndex += 1
|
||||||
try:
|
try:
|
||||||
self.conn.connect(self.server)
|
self.conn.connect(server)
|
||||||
self.conn.settimeout(conf.supybot.drivers.poll())
|
self.conn.settimeout(conf.supybot.drivers.poll())
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
if e.args[0] == 115:
|
if e.args[0] == 115:
|
||||||
@ -172,7 +176,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
'check for %s', whenS)
|
'check for %s', whenS)
|
||||||
schedule.addEvent(self._checkAndWriteOrReconnect, when)
|
schedule.addEvent(self._checkAndWriteOrReconnect, when)
|
||||||
else:
|
else:
|
||||||
log.warning('Error connecting to %s: %s', self.server[0], e)
|
log.warning('Error connecting to %s: %s', self.currentServer,e)
|
||||||
self.reconnect(wait=True)
|
self.reconnect(wait=True)
|
||||||
return
|
return
|
||||||
self.connected = True
|
self.connected = True
|
||||||
@ -186,15 +190,15 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
self.connected = True
|
self.connected = True
|
||||||
self.reconnectWaitPeriodsIndex = 0
|
self.reconnectWaitPeriodsIndex = 0
|
||||||
else:
|
else:
|
||||||
log.warning('Error connecting to %s: Timed out.', self.server[0])
|
log.warning('Error connecting to %s: Timed out.',self.currentServer)
|
||||||
self.reconnect()
|
self.reconnect()
|
||||||
|
|
||||||
def _scheduleReconnect(self):
|
def _scheduleReconnect(self):
|
||||||
when = time.time() + self.reconnectWaits[self.reconnectWaitsIndex]
|
when = time.time() + self.reconnectWaits[self.reconnectWaitsIndex]
|
||||||
if not world.dying:
|
if not world.dying:
|
||||||
whenS = log.timestamp(when)
|
whenS = log.timestamp(when)
|
||||||
server = '%s:%s' % self.server
|
log.info('Scheduling reconnect to %s at %s',
|
||||||
log.info('Scheduling reconnect to %s at %s', server, whenS)
|
self.irc.network, whenS)
|
||||||
schedule.addEvent(self.reconnect, when)
|
schedule.addEvent(self.reconnect, when)
|
||||||
|
|
||||||
def die(self):
|
def die(self):
|
||||||
@ -203,7 +207,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||||||
# self.irc.die() Kill off the ircs yourself, jerk!
|
# self.irc.die() Kill off the ircs yourself, jerk!
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return '%s%s' % (self.__class__.__name__, self.server)
|
return '%s(%s)' % (self.__class__.__name__, self.irc)
|
||||||
|
|
||||||
|
|
||||||
Driver = SocketDriver
|
Driver = SocketDriver
|
||||||
|
@ -92,12 +92,29 @@ class SupyIrcProtocol(LineReceiver):
|
|||||||
class SupyReconnectingFactory(ReconnectingClientFactory):
|
class SupyReconnectingFactory(ReconnectingClientFactory):
|
||||||
maxDelay = 300
|
maxDelay = 300
|
||||||
protocol = SupyIrcProtocol
|
protocol = SupyIrcProtocol
|
||||||
def __init__(self, (server, port), irc):
|
def __init__(self, irc):
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
self.server = (server, port)
|
self.networkGroup = conf.supybot.networks.get(self.irc.network)
|
||||||
reactor.connectTCP(server, port, self)
|
self.servers = ()
|
||||||
|
reactor.connectTCP('', 0, self)
|
||||||
|
|
||||||
|
def _getServers(self):
|
||||||
|
# We do this, rather than itertools.cycle the servers in __init__,
|
||||||
|
# because otherwise registry updates given as setValues or sets
|
||||||
|
# wouldn't be visible until a restart.
|
||||||
|
return self.networkGroup.servers()[:] # Be sure to copy!
|
||||||
|
|
||||||
|
def _getNextServer(self):
|
||||||
|
if not self.servers:
|
||||||
|
self.servers = self._getServers()
|
||||||
|
assert self.servers, 'Servers value for %s is empty.' % \
|
||||||
|
self.networkGroup.name
|
||||||
|
server = self.servers.pop(0)
|
||||||
|
self.currentServer = '%s:%s' % server
|
||||||
|
return server
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
|
addr = self._getNextServer()
|
||||||
protocol = ReconnectingClientFactory.buildProtocol(self, addr)
|
protocol = ReconnectingClientFactory.buildProtocol(self, addr)
|
||||||
protocol.irc = self.irc
|
protocol.irc = self.irc
|
||||||
return protocol
|
return protocol
|
||||||
|
Loading…
Reference in New Issue
Block a user