mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-30 07:27:28 +03:00 
			
		
		
		
	Slightly improve the updates thread (also easier to understand)
This commit is contained in:
		
							parent
							
								
									ceca636bb1
								
							
						
					
					
						commit
						426b09aec0
					
				|  | @ -29,53 +29,41 @@ class MtProtoSender: | |||
|         # We need this to avoid using the updates thread if we're waiting to read | ||||
|         self.waiting_receive = False | ||||
| 
 | ||||
|         self.updates_thread = Thread( | ||||
|             target=self.updates_thread_method, name='Updates thread') | ||||
| 
 | ||||
|         # Signal for correct stopping update thread | ||||
|         self.updates_thread_stopping = False | ||||
| 
 | ||||
|         self.ping_interval = 60 | ||||
|         self.ping_time_last = time() | ||||
| 
 | ||||
|         self.updates_thread_receiving = False | ||||
| 
 | ||||
|         # Determine whether the received acknowledge request confirm | ||||
|         # our requests or not. This is not desired until we initialize | ||||
|         # our connection, because it breaks things when we call InvokeWithLayer | ||||
|         # TODO There might be a better way to handle msgs_ack requests | ||||
|         self.ack_requests_confirm = False | ||||
| 
 | ||||
|         # Always running thread for periodical ping requests | ||||
|         # after all initialization is complete | ||||
|         self.updates_thread.start() | ||||
|         self.ping_interval = 60 | ||||
|         self.ping_time_last = time() | ||||
| 
 | ||||
|         # Variables used to determine the status of the updates thread. | ||||
|         self.updates_thread_running = False | ||||
|         self.updates_thread_receiving = False | ||||
| 
 | ||||
|         self.updates_thread = Thread( | ||||
|             target=self.updates_thread_method, name='Updates thread') | ||||
| 
 | ||||
|         # The "updates" thread must also be running to make periodic ping requests. | ||||
|         self.set_updates_thread(running=True) | ||||
| 
 | ||||
|     def disconnect(self): | ||||
|         """Disconnects and **stops all the running threads** if any""" | ||||
|         self.set_listen_for_updates(enabled=False) | ||||
|         # Stop thread on next loop cycle | ||||
|         self.updates_thread_stopping = True | ||||
|         self.set_updates_thread(running=False) | ||||
|         self.transport.close() | ||||
| 
 | ||||
|     def add_update_handler(self, handler): | ||||
|         """Adds an update handler (a method with one argument, the received | ||||
|            TLObject) that is fired when there are updates available""" | ||||
| 
 | ||||
|         first_handler = not self.on_update_handlers | ||||
|         # The updates thread is already running for periodic ping requests, | ||||
|         # so there is no need to start it when adding update handlers. | ||||
|         self.on_update_handlers.append(handler) | ||||
| 
 | ||||
|         # If this is the first added handler, | ||||
|         # we must start the thread to receive updates | ||||
|         if first_handler: | ||||
|             self.set_listen_for_updates(enabled=True) | ||||
| 
 | ||||
|     def remove_update_handler(self, handler): | ||||
|         self.on_update_handlers.remove(handler) | ||||
| 
 | ||||
|         # If there are no more update handlers, stop the thread | ||||
|         if not self.on_update_handlers: | ||||
|             self.set_listen_for_updates(False) | ||||
| 
 | ||||
|     def generate_sequence(self, confirmed): | ||||
|         """Generates the next sequence number, based on whether it | ||||
|            was confirmed yet or not""" | ||||
|  | @ -357,11 +345,17 @@ class MtProtoSender: | |||
| 
 | ||||
|     # endregion | ||||
| 
 | ||||
|     def set_listen_for_updates(self, enabled): | ||||
|         if enabled: | ||||
|             self.updates_thread_receiving = False | ||||
|         else: | ||||
|             if self.updates_thread_receiving: | ||||
|     def set_updates_thread(self, running): | ||||
|         """Sets the updates thread status (running or not)""" | ||||
|         if running == self.updates_thread_running: | ||||
|             return | ||||
| 
 | ||||
|         # Different state, update the saved value and behave as required | ||||
|         self.updates_thread_running = running | ||||
|         if running: | ||||
|             self.updates_thread.start() | ||||
| 
 | ||||
|         elif self.updates_thread_receiving: | ||||
|             self.transport.cancel_receive() | ||||
| 
 | ||||
|     def updates_thread_method(self): | ||||
|  | @ -370,18 +364,19 @@ class MtProtoSender: | |||
|         # Set a reasonable timeout when checking for updates | ||||
|         timeout = timedelta(minutes=1) | ||||
| 
 | ||||
|         while not self.updates_thread_stopping: | ||||
|         while self.updates_thread_running: | ||||
|             # Only try to receive updates if we're not waiting to receive a request | ||||
|             if not self.waiting_receive: | ||||
|                 with self.lock: | ||||
|                     try: | ||||
|                         now = time() | ||||
|                         # if ping_interval seconds passed since last ping | ||||
|                         # (or startup) - send new one | ||||
|                         # If ping_interval seconds passed since last ping, send a new one | ||||
|                         if now >= self.ping_time_last + self.ping_interval: | ||||
|                             self.ping_time_last = now | ||||
|                             self.send_ping() | ||||
|                             # if sending ping - we doesn't processing any other updates | ||||
| 
 | ||||
|                         # Exit the loop if we're not expecting to receive any updates | ||||
|                         if not self.on_update_handlers: | ||||
|                             continue | ||||
| 
 | ||||
|                         self.updates_thread_receiving = True | ||||
|  | @ -401,5 +396,6 @@ class MtProtoSender: | |||
|             # If we are here, it is because the read was cancelled | ||||
|             # Sleep a bit just to give enough time for the other thread | ||||
|             # to acquire the lock. No need to sleep if we're not running anymore | ||||
|             if not self.updates_thread_stopping: | ||||
|                 sleep(0.1) | ||||
|             if self.updates_thread_running: | ||||
|                 # Longer sleep if we're not expecting any update (only pings) | ||||
|                 sleep(0.1 if self.on_update_handlers else 1) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user