Simplify the workflow with UpdateState exposing a single flag param

This commit is contained in:
Lonami Exo 2017-09-08 12:54:38 +02:00
parent 25bbb20b0c
commit c81537bed0
4 changed files with 32 additions and 32 deletions

View File

@ -58,8 +58,7 @@ class TelegramBareClient:
def __init__(self, session, api_id, api_hash, def __init__(self, session, api_id, api_hash,
connection_mode=ConnectionMode.TCP_FULL, connection_mode=ConnectionMode.TCP_FULL,
proxy=None, proxy=None,
enable_updates=False, process_updates=False,
active_updates_polling=False,
timeout=timedelta(seconds=5)): timeout=timedelta(seconds=5)):
"""Initializes the Telegram client with the specified API ID and Hash. """Initializes the Telegram client with the specified API ID and Hash.
Session must always be a Session instance, and an optional proxy Session must always be a Session instance, and an optional proxy
@ -80,7 +79,7 @@ class TelegramBareClient:
# This member will process updates if enabled. # This member will process updates if enabled.
# One may change self.updates.enabled at any later point. # One may change self.updates.enabled at any later point.
self.updates = UpdateState(enable_updates, active_updates_polling) self.updates = UpdateState(process_updates)
# These will be set later # These will be set later
self.dc_options = None self.dc_options = None

View File

@ -57,8 +57,7 @@ class TelegramClient(TelegramBareClient):
def __init__(self, session, api_id, api_hash, def __init__(self, session, api_id, api_hash,
connection_mode=ConnectionMode.TCP_FULL, connection_mode=ConnectionMode.TCP_FULL,
proxy=None, proxy=None,
enable_updates=False, process_updates=False,
active_updates_polling=False,
timeout=timedelta(seconds=5), timeout=timedelta(seconds=5),
**kwargs): **kwargs):
"""Initializes the Telegram client with the specified API ID and Hash. """Initializes the Telegram client with the specified API ID and Hash.
@ -72,18 +71,15 @@ class TelegramClient(TelegramBareClient):
This will only affect how messages are sent over the network This will only affect how messages are sent over the network
and how much processing is required before sending them. and how much processing is required before sending them.
If 'enable_updates' is set to True, it will process incoming If 'process_updates' is set to True, incoming updates will be
updates to ensure that no duplicates are received, and update processed and you must manually call 'self.updates.poll()' from
handlers will be invoked. You CANNOT invoke requests from within another thread to retrieve the saved update objects, or your
these handlers. memory will fill with these. You may modify the value of
'self.updates.polling' at any later point.
In order to invoke requests upon receiving an update, you must Despite the value of 'process_updates', if you later call
have your own thread (or use the main thread) and enable set '.add_update_handler(...)', updates will also be processed
'active_updates_polling' to True. You must call self.updates.poll() and the update objects will be passed to the handlers you added.
or you'll memory will be filled with unhandled updates.
You can also modify 'self.updates.enabled' and
'self.updates.set_polling()' at any later point.
If more named arguments are provided as **kwargs, they will be If more named arguments are provided as **kwargs, they will be
used to update the Session instance. Most common settings are: used to update the Session instance. Most common settings are:
@ -110,8 +106,7 @@ class TelegramClient(TelegramBareClient):
session, api_id, api_hash, session, api_id, api_hash,
connection_mode=connection_mode, connection_mode=connection_mode,
proxy=proxy, proxy=proxy,
enable_updates=enable_updates, process_updates=process_updates,
active_updates_polling=active_updates_polling,
timeout=timeout timeout=timeout
) )
@ -922,7 +917,10 @@ class TelegramClient(TelegramBareClient):
def add_update_handler(self, handler): def add_update_handler(self, handler):
"""Adds an update handler (a function which takes a TLObject, """Adds an update handler (a function which takes a TLObject,
an update, as its parameter) and listens for updates""" an update, as its parameter) and listens for updates"""
sync = not self.updates.handlers
self.updates.handlers.append(handler) self.updates.handlers.append(handler)
if sync:
self.sync_updates()
def remove_update_handler(self, handler): def remove_update_handler(self, handler):
self.updates.handlers.remove(handler) self.updates.handlers.remove(handler)

View File

@ -7,11 +7,10 @@ from .tl import types as tl
class UpdateState: class UpdateState:
"""Used to hold the current state of processed updates. """Used to hold the current state of processed updates.
To retrieve an update, .pop_update() should be called. To retrieve an update, .poll() should be called.
""" """
def __init__(self, enabled, store_updates): def __init__(self, polling):
self.enabled = enabled self._polling = polling
self._store_updates = store_updates
self.handlers = [] self.handlers = []
self._updates_lock = RLock() self._updates_lock = RLock()
self._updates_available = Event() self._updates_available = Event()
@ -20,14 +19,14 @@ class UpdateState:
# https://core.telegram.org/api/updates # https://core.telegram.org/api/updates
self._state = tl.updates.State(0, 0, datetime.now(), 0, 0) self._state = tl.updates.State(0, 0, datetime.now(), 0, 0)
def has_any(self): def can_poll(self):
"""Returns True if a call to .pop_update() won't lock""" """Returns True if a call to .poll() won't lock"""
return self._updates_available.is_set() return self._updates_available.is_set()
def poll(self): def poll(self):
"""Polls an update or blocks until an update object is available""" """Polls an update or blocks until an update object is available"""
if not self._store_updates: if not self._polling:
raise ValueError('Polling updates is not enabled.') raise ValueError('Updates are not being polled hence not saved.')
self._updates_available.wait() self._updates_available.wait()
with self._updates_lock: with self._updates_lock:
@ -37,17 +36,22 @@ class UpdateState:
return update return update
def set_polling(self, store): def get_polling(self):
self._store_updates = store return self._polling
if not store:
def set_polling(self, polling):
self._polling = polling
if not polling:
with self._updates_lock: with self._updates_lock:
self._updates.clear() self._updates.clear()
polling = property(fget=get_polling, fset=set_polling)
def process(self, update): def process(self, update):
"""Processes an update object. This method is normally called by """Processes an update object. This method is normally called by
the library itself. the library itself.
""" """
if not self.enabled: if not self._polling or not self.handlers:
return return
with self._updates_lock: with self._updates_lock:
@ -58,6 +62,6 @@ class UpdateState:
for handler in self.handlers: for handler in self.handlers:
handler(update) handler(update)
if self._store_updates: if self._polling:
self._updates.append(update) self._updates.append(update)
self._updates_available.set() self._updates_available.set()

View File

@ -52,7 +52,6 @@ class InteractiveTelegramClient(TelegramClient):
super().__init__( super().__init__(
session_user_id, api_id, api_hash, session_user_id, api_id, api_hash,
connection_mode=ConnectionMode.TCP_ABRIDGED, connection_mode=ConnectionMode.TCP_ABRIDGED,
enable_updates=True,
proxy=proxy proxy=proxy
) )