From 30daca8457e435b6a94f9c8d0c38db685c59b258 Mon Sep 17 00:00:00 2001 From: Shiz Date: Sat, 22 Feb 2014 20:57:32 +0100 Subject: [PATCH] Update ClientPool to work with the asynchronous changes. This closes #21. --- README.md | 9 ++++---- pydle/client.py | 57 +++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 30c483b..60f1689 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,7 @@ No worries! Use `pydle.ClientPool` like such: pool = pydle.ClientPool() for i in range(10): client = MyOwnBot('MyBot' + str(i)) - client.connect('irc.rizon.net', 6697, tls=True, tls_verify=False) - pool.add(client) + pool.connect(client, 'irc.rizon.net', 6697, tls=True, tls_verify=False) # This will make sure all clients are treated in a fair way priority-wise. pool.handle_forever() @@ -349,11 +348,11 @@ You can also overload `Client.on_raw_(message)`, where `cmd` is the raw IRC **pydle.ClientPool** -`ClientPool(clients)` - instantiate a pool with `clients` as initial clients. +`ClientPool()` - instantiate a new pool. It is very advised to have only one pool per thread, and to not have a single client participate in more than one pool. -`ClientPool.add(client)` - add client to pool. +`ClientPool.connect(client, *args, **kwargs)` - add client to pool and connect it. Parameters are passed to `client.connect()`, except for `eventloop`, which is replaced. -`ClientPool.remove(client)` - remove client from pool. +`ClientPool.disconnect(client)` - disconnect client and remove it from pool. `ClientPool.handle_forever()` - handle clients in pool forever. diff --git a/pydle/client.py b/pydle/client.py index d3e61bf..de72d65 100644 --- a/pydle/client.py +++ b/pydle/client.py @@ -414,49 +414,46 @@ class BasicClient: class ClientPool: """ A pool of clients. """ - def __init__(self, clients=None): + def __init__(self, clients=None, eventloop=None): + if not eventloop: + self.eventloop = async.EventLoop() + else: + self.eventloop = eventloop if not clients: - clients = [] - - self.clients = set(clients) - self.client_cycle = itertools.cycle(self.clients) - self.connpool = connection.ConnectionPool(client.connection for client in self.clients) + self.clients = set() + else: + self.clients = set(clients) def add(self, client): """ Add client to pool. """ self.clients.add(client) - self.client_cycle = itertools.cycle(self.clients) - self.connpool = connection.ConnectionPool(client.connection for client in self.clients) def remove(self, client): """ Remove client from pool. """ self.clients.remove(client) - self.client_cycle = itertools.cycle(self.clients) - self.connpool = connection.ConnectionPool(client.connection for client in self.clients) + + def __contains__(self, item): + return item in self.clients - ## High-level message stuff. + ## High-level. - def has_message(self): - return self.connpool.has_message() + def connect(self, client, *args, eventloop=None, **kwargs): + if client not in self: + self.add(client) + client.connect(*args, eventloop=self.eventloop, **kwargs) - def handle_message(self): - """ - Handle first available message from any client in the pool. - Tries to be fair towards clients by cycling the start client tries to take a message from. - """ - if not self.has_message(): - raise connection.NoMessageAvailable('No message available.') + def disconnect(self, client, *args, **kwargs): + if client not in self: + return + client.disconnect(*args, **kwargs) + self.remove(client) - for client in self.client_cycle: - if client._has_message(): - return client.poll_single() + def handle_forever(self): + for client in self.clients: + client.connection.setup_handlers() - def poll_forever(self): - """ Enter infinite handle loop. """ - while True: - self.poll_single() - self.handle_message() + self.eventloop.run() - def poll_single(self): - return self.connpool.wait_for_message() + for client in self.clients: + client.connection.remove_handlers()