From 576ac666d9848ac2a6d86e966d905075c1ff39d1 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 27 Aug 2018 01:19:37 +0200 Subject: [PATCH] Fix resolving events while disconnected --- telethon/client/updates.py | 5 ++--- telethon/events/common.py | 38 +++++++++++++++-------------------- telethon/events/newmessage.py | 7 +++---- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/telethon/client/updates.py b/telethon/client/updates.py index 57cd4962..e92f1348 100644 --- a/telethon/client/updates.py +++ b/telethon/client/updates.py @@ -89,7 +89,6 @@ class UpdateMethods(UserMethods): elif not event: event = events.Raw() - event.ensure_resolve(self) self._event_builders.append((event, callback)) def remove_event_handler(self, callback, event=None): @@ -266,8 +265,8 @@ class UpdateMethods(UserMethods): if not event: continue - if not builder.resolved.is_set(): - await builder.resolved.wait() + if not builder.resolved: + await builder.resolve() if not builder.filter(event): continue diff --git a/telethon/events/common.py b/telethon/events/common.py index 7c706e66..8c3d3360 100644 --- a/telethon/events/common.py +++ b/telethon/events/common.py @@ -58,37 +58,31 @@ class EventBuilder(abc.ABC): def __init__(self, chats=None, blacklist_chats=False): self.chats = chats self.blacklist_chats = blacklist_chats - self.resolved = None + self.resolved = False + self._resolve_lock = None @classmethod @abc.abstractmethod def build(cls, update): """Builds an event for the given update if possible, or returns None""" - def ensure_resolve(self, client): - """ - Sets the event loop so that self.resolved can be used. - - The expected workflow is: - 1. Creating the event builder. - 2a. Calling `ensure_resolve`. - 2b. Awaiting `resolved.wait`. - OR - 2a. Awaiting `resolve`. - 3. Using `filter`. - """ - if not self.resolved: - self.resolved = asyncio.Event(loop=client.loop) - client.loop.create_task(self.resolve(client)) - async def resolve(self, client): """Helper method to allow event builders to be resolved before usage""" - if not self.resolved.is_set(): - self.chats = await _into_id_set(client, self.chats) - if not EventBuilder.self_id: - EventBuilder.self_id = await client.get_peer_id('me') + if self.resolved: + return - self.resolved.set() + if not self._resolve_lock: + self._resolve_lock = asyncio.Lock(loop=client.loop) + + async with self._resolve_lock: + if not self.resolved: + await self._resolve(client) + self.resolved = True + + async def _resolve(self, client): + self.chats = await _into_id_set(client, self.chats) + if not EventBuilder.self_id: + EventBuilder.self_id = await client.get_peer_id('me') def filter(self, event): """ diff --git a/telethon/events/newmessage.py b/telethon/events/newmessage.py index b2ee33e1..12d3e7cb 100644 --- a/telethon/events/newmessage.py +++ b/telethon/events/newmessage.py @@ -71,10 +71,9 @@ class NewMessage(EventBuilder): self.from_users, self.forwards, self.from_users )) - async def resolve(self, client): - if not self.resolved.is_set(): - self.from_users = await _into_id_set(client, self.from_users) - await super().resolve(client) + async def _resolve(self, client): + await super()._resolve(client) + self.from_users = await _into_id_set(client, self.from_users) @classmethod def build(cls, update):