Allow adding update handlers without the need to poll updates

This commit is contained in:
Lonami Exo 2017-09-07 20:29:51 +02:00
parent b8e881b6b6
commit a24b4020fe
3 changed files with 32 additions and 11 deletions

View File

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

View File

@ -60,6 +60,7 @@ class TelegramClient(TelegramBareClient):
connection_mode=ConnectionMode.TCP_FULL,
proxy=None,
enable_updates=False,
active_updates_polling=False,
timeout=timedelta(seconds=5),
**kwargs):
"""Initializes the Telegram client with the specified API ID and Hash.
@ -73,11 +74,18 @@ class TelegramClient(TelegramBareClient):
This will only affect how messages are sent over the network
and how much processing is required before sending them.
If 'enable_updates' is set to True, it will by default put
all updates on self.updates. NOTE that you must manually query
this from another thread or it will eventually fill up all your
memory. If you want to ignore updates, leave this set to False.
You may change self.updates.enabled at any later point.
If 'enable_updates' is set to True, it will process incoming
updates to ensure that no duplicates are received, and update
handlers will be invoked. You CANNOT invoke requests from within
these handlers.
In order to invoke requests upon receiving an update, you must
have your own thread (or use the main thread) and enable set
'active_updates_polling' to True. You must call self.updates.poll()
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
used to update the Session instance. Most common settings are:
@ -105,6 +113,7 @@ class TelegramClient(TelegramBareClient):
connection_mode=connection_mode,
proxy=proxy,
enable_updates=enable_updates,
active_updates_polling=active_updates_polling,
timeout=timeout
)

View File

@ -9,8 +9,9 @@ class UpdateState:
"""Used to hold the current state of processed updates.
To retrieve an update, .pop_update() should be called.
"""
def __init__(self, enabled):
def __init__(self, enabled, store_updates):
self.enabled = enabled
self._store_updates = store_updates
self.handlers = []
self._updates_lock = RLock()
self._updates_available = Event()
@ -23,8 +24,11 @@ class UpdateState:
"""Returns True if a call to .pop_update() won't lock"""
return self._updates_available.is_set()
def pop(self):
"""Pops an update or blocks until an update object is available"""
def poll(self):
"""Polls an update or blocks until an update object is available"""
if not self._store_updates:
raise ValueError('Polling updates is not enabled.')
self._updates_available.wait()
with self._updates_lock:
update = self._updates.popleft()
@ -33,6 +37,12 @@ class UpdateState:
return update
def set_polling(self, store):
self._store_updates = store
if not store:
with self._updates_lock:
self._updates.clear()
def process(self, update):
"""Processes an update object. This method is normally called by
the library itself.
@ -48,5 +58,6 @@ class UpdateState:
for handler in self.handlers:
handler(update)
self._updates.append(update)
self._updates_available.set()
if self._store_updates:
self._updates.append(update)
self._updates_available.set()