From bb607e56be6e219582d96f28aa318b5a37cfa96c Mon Sep 17 00:00:00 2001 From: JosXa Date: Mon, 30 Apr 2018 00:15:24 +0200 Subject: [PATCH 1/2] Added locks for modifying and iterating handlers Added `remove_handler` method Made `add_handler` return a (handler, group) tuple --- pyrogram/client/client.py | 18 +++++++- pyrogram/client/dispatcher/dispatcher.py | 55 ++++++++++++++---------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 07679545..8fb3e500 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -245,7 +245,7 @@ class Client: return decorator def add_handler(self, handler, group: int = 0): - """Use this method to register an event handler. + """Use this method to register an update handler. You can register multiple handlers, but at most one handler within a group will be used for a single event. To handle the same event more than once, register @@ -260,6 +260,22 @@ class Client: """ self.dispatcher.add_handler(handler, group) + def remove_handler(self, handler, group: int = 0): + """Removes a previously-added update handler. + + Make sure to provide the right group that the handler was added in. You can use + the return value of the ``add_handler`` method, a tuple of (handler, group), and + pass it directly. + + Args: + handler (``Handler``): + The handler to be removed. + + group (``int``, optional): + The group identifier, defaults to 0. + """ + self.dispatcher.remove_handler(handler, group) + def start(self, debug: bool = False): """Use this method to start the Client after creating it. Requires no parameters. diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 6f96876c..cf6912f5 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -50,6 +50,8 @@ class Dispatcher: self.updates = Queue() self.groups = OrderedDict() + self._handler_lock = threading.Lock() + def start(self): for i in range(self.workers): self.workers_list.append( @@ -69,36 +71,45 @@ class Dispatcher: i.join() def add_handler(self, handler, group: int): - if group not in self.groups: - self.groups[group] = [] - self.groups = OrderedDict(sorted(self.groups.items())) + with self._handler_lock: + if group not in self.groups: + self.groups[group] = [] + self.groups = OrderedDict(sorted(self.groups.items())) - self.groups[group].append(handler) + self.groups[group].append(handler) + + def remove_handler(self, handler, group: int): + with self._handler_lock: + if group not in self.groups: + raise ValueError("Group {} does not exist. " + "Handler was not removed.".format(group)) + self.groups[group].remove(handler) def dispatch(self, update, users: dict = None, chats: dict = None, is_raw: bool = False): - for group in self.groups.values(): - for handler in group: - if is_raw: - if not isinstance(handler, RawUpdateHandler): - continue + with self._handler_lock: + for group in self.groups.values(): + for handler in group: + if is_raw: + if not isinstance(handler, RawUpdateHandler): + continue - args = (self.client, update, users, chats) - else: - if not isinstance(handler, MessageHandler): - continue + args = (self.client, update, users, chats) + else: + if not isinstance(handler, MessageHandler): + continue - message = (update.message - or update.channel_post - or update.edited_message - or update.edited_channel_post) + message = (update.message + or update.channel_post + or update.edited_message + or update.edited_channel_post) - if not handler.check(message): - continue + if not handler.check(message): + continue - args = (self.client, message) + args = (self.client, message) - handler.callback(*args) - break + handler.callback(*args) + break def update_worker(self): name = threading.current_thread().name From f824e69b5a2449fd01121f75b504235fc15c1a47 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 30 Apr 2018 10:15:34 +0200 Subject: [PATCH 2/2] Update client.py --- pyrogram/client/client.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 8fb3e500..1a8b2578 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -243,12 +243,13 @@ class Client: return func return decorator - + + # TODO: Maybe make add_handler return (handler, group)? def add_handler(self, handler, group: int = 0): """Use this method to register an update handler. You can register multiple handlers, but at most one handler within a group - will be used for a single event. To handle the same event more than once, register + will be used for a single update. To handle the same update more than once, register your handler using a different group id (lower group id == higher priority). Args: @@ -264,7 +265,7 @@ class Client: """Removes a previously-added update handler. Make sure to provide the right group that the handler was added in. You can use - the return value of the ``add_handler`` method, a tuple of (handler, group), and + the return value of the :meth:`add_handler` method, a tuple of (handler, group), and pass it directly. Args: