Skip to content

Commit 280a700

Browse files
committed
Attempt at not calling .connect for every file chunk
1 parent 9907d76 commit 280a700

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

telethon/telegram_bare_client.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -416,23 +416,33 @@ def _get_cdn_client(self, cdn_redirect):
416416

417417
# region Invoking Telegram requests
418418

419-
def __call__(self, *requests, retries=5):
419+
def _get_sender(self, on_main_thread=None):
420+
"""Gets the appropriated sender based on the current thread"""
421+
if on_main_thread is None:
422+
on_main_thread = threading.get_ident() == self._main_thread_ident
423+
424+
if on_main_thread or self._on_read_thread():
425+
sender = self._sender
426+
else:
427+
sender = self._sender.clone()
428+
sender.connect()
429+
return sender
430+
431+
def __call__(self, *requests, retries=5, sender=None):
420432
"""Invokes (sends) a MTProtoRequest and returns (receives) its result.
421433
422434
The invoke will be retried up to 'retries' times before raising
423435
ValueError().
436+
437+
If 'sender' is not None, it will override the sender to be used.
424438
"""
425439
if not all(isinstance(x, TLObject) and
426440
x.content_related for x in requests):
427441
raise ValueError('You can only invoke requests, not types!')
428442

429443
# Determine the sender to be used (main or a new connection)
430444
on_main_thread = threading.get_ident() == self._main_thread_ident
431-
if on_main_thread or self._on_read_thread():
432-
sender = self._sender
433-
else:
434-
sender = self._sender.clone()
435-
sender.connect()
445+
sender = sender or self._get_sender(on_main_thread=on_main_thread)
436446

437447
# We should call receive from this thread if there's no background
438448
# thread reading or if the server disconnected us and we're trying
@@ -686,6 +696,10 @@ def download_file(self,
686696

687697
# The used client will change if FileMigrateError occurs
688698
client = self
699+
# TODO Keeping just another variable for a sender feels messy, improve.
700+
# This is done not to call .connect() for every single piece of the
701+
# file we'll be trying to download, if we were from another thread.
702+
sender = self._get_sender()
689703
cdn_decrypter = None
690704

691705
try:
@@ -697,7 +711,7 @@ def download_file(self,
697711
else:
698712
result = client(GetFileRequest(
699713
input_location, offset, part_size
700-
))
714+
), sender=sender)
701715

702716
if isinstance(result, FileCdnRedirect):
703717
cdn_decrypter, result = \
@@ -706,7 +720,11 @@ def download_file(self,
706720
)
707721

708722
except FileMigrateError as e:
723+
if sender != self._sender:
724+
sender.disconnect()
709725
client = self._get_exported_client(e.new_dc)
726+
# Client connected on this thread -> uses the right sender
727+
sender = None
710728
continue
711729

712730
offset += part_size
@@ -721,6 +739,8 @@ def download_file(self,
721739
if progress_callback:
722740
progress_callback(f.tell(), file_size)
723741
finally:
742+
if sender != self._sender:
743+
sender.disconnect()
724744
if client != self:
725745
client.disconnect()
726746

0 commit comments

Comments
 (0)