Allow sending ordered MessageContainer

This commit is contained in:
Lonami Exo 2018-05-09 09:46:07 +02:00
parent bda7eb0ef1
commit e200acbca8
2 changed files with 23 additions and 8 deletions

View File

@ -2,7 +2,6 @@
This module contains the class used to communicate with Telegram's servers This module contains the class used to communicate with Telegram's servers
encrypting every packet, and relies on a valid AuthKey in the used Session. encrypting every packet, and relies on a valid AuthKey in the used Session.
""" """
import gzip
import logging import logging
from threading import Lock from threading import Lock
@ -14,6 +13,7 @@ from ..errors import (
from ..extensions import BinaryReader from ..extensions import BinaryReader
from ..tl import TLMessage, MessageContainer, GzipPacked from ..tl import TLMessage, MessageContainer, GzipPacked
from ..tl.all_tlobjects import tlobjects from ..tl.all_tlobjects import tlobjects
from ..tl.functions import InvokeAfterMsgRequest
from ..tl.functions.auth import LogOutRequest from ..tl.functions.auth import LogOutRequest
from ..tl.types import ( from ..tl.types import (
MsgsAck, Pong, BadServerSalt, BadMsgNotification, FutureSalts, MsgsAck, Pong, BadServerSalt, BadMsgNotification, FutureSalts,
@ -84,15 +84,26 @@ class MtProtoSender:
# region Send and receive # region Send and receive
def send(self, *requests): def send(self, *requests, ordered=False):
""" """
Sends the specified TLObject(s) (which must be requests), Sends the specified TLObject(s) (which must be requests),
and acknowledging any message which needed confirmation. and acknowledging any message which needed confirmation.
:param requests: the requests to be sent. :param requests: the requests to be sent.
:param ordered: whether the requests should be invoked in the
order in which they appear or they can be executed
in arbitrary order in the server.
""" """
# Finally send our packed request(s) if ordered:
messages = [TLMessage(self.session, r) for r in requests] requests = iter(requests)
messages = [TLMessage(self.session, next(requests))]
for r in requests:
messages.append(TLMessage(
self.session, InvokeAfterMsgRequest(messages[-1].msg_id, r)
))
else:
messages = [TLMessage(self.session, r) for r in requests]
self._pending_receive.update({m.msg_id: m for m in messages}) self._pending_receive.update({m.msg_id: m for m in messages})
__log__.debug('Sending requests with IDs: %s', ', '.join( __log__.debug('Sending requests with IDs: %s', ', '.join(

View File

@ -429,11 +429,15 @@ class TelegramBareClient:
# region Invoking Telegram requests # region Invoking Telegram requests
def __call__(self, *requests, retries=5): def __call__(self, *requests, retries=5, ordered=False):
"""Invokes (sends) a MTProtoRequest and returns (receives) its result. """Invokes (sends) a MTProtoRequest and returns (receives) its result.
The invoke will be retried up to 'retries' times before raising The invoke will be retried up to 'retries' times before raising
RuntimeError(). RuntimeError().
If more than one request is given and ordered is True, then the
requests will be invoked sequentially in the server (useful for
bursts of requests that need to be ordered).
""" """
if not all(isinstance(x, TLObject) and if not all(isinstance(x, TLObject) and
x.content_related for x in requests): x.content_related for x in requests):
@ -458,7 +462,7 @@ class TelegramBareClient:
not self._idling.is_set() or self._reconnect_lock.locked() not self._idling.is_set() or self._reconnect_lock.locked()
for retry in range(retries): for retry in range(retries):
result = self._invoke(call_receive, *requests) result = self._invoke(call_receive, *requests, ordered=ordered)
if result is not None: if result is not None:
return result return result
@ -481,7 +485,7 @@ class TelegramBareClient:
# Let people use client.invoke(SomeRequest()) instead client(...) # Let people use client.invoke(SomeRequest()) instead client(...)
invoke = __call__ invoke = __call__
def _invoke(self, call_receive, *requests): def _invoke(self, call_receive, *requests, ordered=False):
try: try:
# Ensure that we start with no previous errors (i.e. resending) # Ensure that we start with no previous errors (i.e. resending)
for x in requests: for x in requests:
@ -506,7 +510,7 @@ class TelegramBareClient:
self._wrap_init_connection(GetConfigRequest()) self._wrap_init_connection(GetConfigRequest())
) )
self._sender.send(*requests) self._sender.send(*requests, ordered=ordered)
if not call_receive: if not call_receive:
# TODO This will be slightly troublesome if we allow # TODO This will be slightly troublesome if we allow