| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | __all__ = ( | 
					
						
							|  |  |  |     'Queue', | 
					
						
							|  |  |  |     'PriorityQueue', | 
					
						
							|  |  |  |     'LifoQueue', | 
					
						
							|  |  |  |     'QueueFull', | 
					
						
							|  |  |  |     'QueueEmpty', | 
					
						
							|  |  |  |     'QueueShutDown', | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import collections | 
					
						
							|  |  |  | import heapq | 
					
						
							| 
									
										
										
										
											2022-01-22 16:58:53 +05:30
										 |  |  | from types import GenericAlias | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | from . import locks | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  | from . import mixins | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  | class QueueEmpty(Exception): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |     """Raised when Queue.get_nowait() is called on an empty Queue.""" | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class QueueFull(Exception): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |     """Raised when the Queue.put_nowait() method is called on a full Queue.""" | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | class QueueShutDown(Exception): | 
					
						
							|  |  |  |     """Raised when putting on to or getting from a shut-down Queue.""" | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-25 13:50:44 +02:00
										 |  |  | class Queue(mixins._LoopBoundMixin): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     """A queue, useful for coordinating producer and consumer coroutines.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If maxsize is less than or equal to zero, the queue size is infinite. If it | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     is an integer greater than 0, then "await put()" will block when the | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     queue reaches maxsize, until an item is removed by get(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unlike the standard library Queue, you can reliably know this Queue's size | 
					
						
							| 
									
										
										
										
											2013-12-13 10:57:04 +01:00
										 |  |  |     with qsize(), since your single-threaded asyncio application won't be | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     interrupted between calling qsize() and doing an operation on the Queue. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 13:25:52 +02:00
										 |  |  |     def __init__(self, maxsize=0): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self._maxsize = maxsize | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Futures. | 
					
						
							|  |  |  |         self._getters = collections.deque() | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         # Futures. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self._putters = collections.deque() | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  |         self._unfinished_tasks = 0 | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |         self._finished = locks.Event() | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  |         self._finished.set() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self._init(maxsize) | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |         self._is_shutdown = False | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 09:24:24 -07:00
										 |  |  |     # These three are overridable in subclasses. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def _init(self, maxsize): | 
					
						
							|  |  |  |         self._queue = collections.deque() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get(self): | 
					
						
							|  |  |  |         return self._queue.popleft() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _put(self, item): | 
					
						
							|  |  |  |         self._queue.append(item) | 
					
						
							| 
									
										
										
										
											2015-04-20 09:24:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # End of the overridable methods. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |     def _wakeup_next(self, waiters): | 
					
						
							|  |  |  |         # Wake up the next waiter (if any) that isn't cancelled. | 
					
						
							|  |  |  |         while waiters: | 
					
						
							|  |  |  |             waiter = waiters.popleft() | 
					
						
							|  |  |  |             if not waiter.done(): | 
					
						
							|  |  |  |                 waiter.set_result(None) | 
					
						
							|  |  |  |                 break | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         return f'<{type(self).__name__} at {id(self):#x} {self._format()}>' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         return f'<{type(self).__name__} {self._format()}>' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 16:58:53 +05:30
										 |  |  |     __class_getitem__ = classmethod(GenericAlias) | 
					
						
							| 
									
										
										
										
											2019-12-07 14:05:07 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def _format(self): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         result = f'maxsize={self._maxsize!r}' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         if getattr(self, '_queue', None): | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             result += f' _queue={list(self._queue)!r}' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         if self._getters: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             result += f' _getters[{len(self._getters)}]' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         if self._putters: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             result += f' _putters[{len(self._putters)}]' | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  |         if self._unfinished_tasks: | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             result += f' tasks={self._unfinished_tasks}' | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |         if self._is_shutdown: | 
					
						
							|  |  |  |             result += ' shutdown' | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def qsize(self): | 
					
						
							|  |  |  |         """Number of items in the queue.""" | 
					
						
							|  |  |  |         return len(self._queue) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def maxsize(self): | 
					
						
							|  |  |  |         """Number of items allowed in the queue.""" | 
					
						
							|  |  |  |         return self._maxsize | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def empty(self): | 
					
						
							|  |  |  |         """Return True if the queue is empty, False otherwise.""" | 
					
						
							|  |  |  |         return not self._queue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def full(self): | 
					
						
							|  |  |  |         """Return True if there are maxsize items in the queue.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Note: if the Queue was initialized with maxsize=0 (the default), | 
					
						
							|  |  |  |         then full() is never True. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if self._maxsize <= 0: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-06-17 23:36:21 +02:00
										 |  |  |             return self.qsize() >= self._maxsize | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def put(self, item): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """Put an item into the queue.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 22:09:50 +01:00
										 |  |  |         Put an item into the queue. If the queue is full, wait until a free | 
					
						
							|  |  |  |         slot is available before adding item. | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Raises QueueShutDown if the queue has been shut down. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         while self.full(): | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |             if self._is_shutdown: | 
					
						
							|  |  |  |                 raise QueueShutDown | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |             putter = self._get_loop().create_future() | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |             self._putters.append(putter) | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |                 await putter | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 putter.cancel()  # Just in case putter is not done yet. | 
					
						
							| 
									
										
										
										
											2018-01-25 23:45:43 +00:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     # Clean self._putters from canceled putters. | 
					
						
							|  |  |  |                     self._putters.remove(putter) | 
					
						
							|  |  |  |                 except ValueError: | 
					
						
							|  |  |  |                     # The putter could be removed from self._putters by a | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |                     # previous get_nowait call or a shutdown call. | 
					
						
							| 
									
										
										
										
											2018-01-25 23:45:43 +00:00
										 |  |  |                     pass | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |                 if not self.full() and not putter.cancelled(): | 
					
						
							|  |  |  |                     # We were woken up by get_nowait(), but can't take | 
					
						
							|  |  |  |                     # the call.  Wake up the next in line. | 
					
						
							|  |  |  |                     self._wakeup_next(self._putters) | 
					
						
							|  |  |  |                 raise | 
					
						
							|  |  |  |         return self.put_nowait(item) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def put_nowait(self, item): | 
					
						
							|  |  |  |         """Put an item into the queue without blocking.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |         If no free slot is immediately available, raise QueueFull. | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Raises QueueShutDown if the queue has been shut down. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |         if self._is_shutdown: | 
					
						
							|  |  |  |             raise QueueShutDown | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         if self.full(): | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |             raise QueueFull | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         self._put(item) | 
					
						
							|  |  |  |         self._unfinished_tasks += 1 | 
					
						
							|  |  |  |         self._finished.clear() | 
					
						
							|  |  |  |         self._wakeup_next(self._getters) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def get(self): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """Remove and return an item from the queue.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 22:09:50 +01:00
										 |  |  |         If queue is empty, wait until an item is available. | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Raises QueueShutDown if the queue has been shut down and is empty, or | 
					
						
							|  |  |  |         if the queue has been shut down immediately. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         while self.empty(): | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |             if self._is_shutdown and self.empty(): | 
					
						
							|  |  |  |                 raise QueueShutDown | 
					
						
							| 
									
										
										
										
											2020-11-24 20:08:54 +02:00
										 |  |  |             getter = self._get_loop().create_future() | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |             self._getters.append(getter) | 
					
						
							| 
									
										
										
										
											2015-08-05 13:52:33 -04:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |                 await getter | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 getter.cancel()  # Just in case getter is not done yet. | 
					
						
							| 
									
										
										
										
											2017-11-07 09:35:23 -08:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2018-01-25 23:45:43 +00:00
										 |  |  |                     # Clean self._getters from canceled getters. | 
					
						
							| 
									
										
										
										
											2017-11-07 09:35:23 -08:00
										 |  |  |                     self._getters.remove(getter) | 
					
						
							|  |  |  |                 except ValueError: | 
					
						
							| 
									
										
										
										
											2018-01-25 23:45:43 +00:00
										 |  |  |                     # The getter could be removed from self._getters by a | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |                     # previous put_nowait call, or a shutdown call. | 
					
						
							| 
									
										
										
										
											2017-11-07 09:35:23 -08:00
										 |  |  |                     pass | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |                 if not self.empty() and not getter.cancelled(): | 
					
						
							|  |  |  |                     # We were woken up by put_nowait(), but can't take | 
					
						
							|  |  |  |                     # the call.  Wake up the next in line. | 
					
						
							|  |  |  |                     self._wakeup_next(self._getters) | 
					
						
							| 
									
										
										
										
											2015-08-05 13:52:33 -04:00
										 |  |  |                 raise | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         return self.get_nowait() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_nowait(self): | 
					
						
							|  |  |  |         """Remove and return an item from the queue.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |         Return an item if one is immediately available, else raise QueueEmpty. | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Raises QueueShutDown if the queue has been shut down and is empty, or | 
					
						
							|  |  |  |         if the queue has been shut down immediately. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         if self.empty(): | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |             if self._is_shutdown: | 
					
						
							|  |  |  |                 raise QueueShutDown | 
					
						
							| 
									
										
										
										
											2014-01-25 17:24:51 -08:00
										 |  |  |             raise QueueEmpty | 
					
						
							| 
									
										
										
										
											2015-09-28 07:42:34 -07:00
										 |  |  |         item = self._get() | 
					
						
							|  |  |  |         self._wakeup_next(self._putters) | 
					
						
							|  |  |  |         return item | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  |     def task_done(self): | 
					
						
							|  |  |  |         """Indicate that a formerly enqueued task is complete.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Used by queue consumers. For each get() used to fetch a task, | 
					
						
							|  |  |  |         a subsequent call to task_done() tells the queue that the processing | 
					
						
							|  |  |  |         on the task is complete. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         If a join() is currently blocking, it will resume when all items have | 
					
						
							|  |  |  |         been processed (meaning that a task_done() call was received for every | 
					
						
							|  |  |  |         item that had been put() into the queue). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Raises ValueError if called more times than there were items placed in | 
					
						
							|  |  |  |         the queue. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if self._unfinished_tasks <= 0: | 
					
						
							|  |  |  |             raise ValueError('task_done() called too many times') | 
					
						
							|  |  |  |         self._unfinished_tasks -= 1 | 
					
						
							|  |  |  |         if self._unfinished_tasks == 0: | 
					
						
							|  |  |  |             self._finished.set() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def join(self): | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  |         """Block until all items in the queue have been gotten and processed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The count of unfinished tasks goes up whenever an item is added to the | 
					
						
							|  |  |  |         queue. The count goes down whenever a consumer calls task_done() to | 
					
						
							|  |  |  |         indicate that the item was retrieved and all work on it is complete. | 
					
						
							|  |  |  |         When the count of unfinished tasks drops to zero, join() unblocks. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if self._unfinished_tasks > 0: | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |             await self._finished.wait() | 
					
						
							| 
									
										
										
										
											2015-02-17 22:53:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |     def shutdown(self, immediate=False): | 
					
						
							|  |  |  |         """Shut-down the queue, making queue gets and puts raise QueueShutDown.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         By default, gets will only raise once the queue is empty. Set | 
					
						
							|  |  |  |         'immediate' to True to make gets raise immediately instead. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-25 07:56:28 -06:00
										 |  |  |         All blocked callers of put() and get() will be unblocked. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         If 'immediate', the queue is drained and unfinished tasks | 
					
						
							|  |  |  |         is reduced by the number of drained tasks.  If unfinished tasks | 
					
						
							|  |  |  |         is reduced to zero, callers of Queue.join are unblocked. | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         self._is_shutdown = True | 
					
						
							|  |  |  |         if immediate: | 
					
						
							|  |  |  |             while not self.empty(): | 
					
						
							|  |  |  |                 self._get() | 
					
						
							|  |  |  |                 if self._unfinished_tasks > 0: | 
					
						
							|  |  |  |                     self._unfinished_tasks -= 1 | 
					
						
							|  |  |  |             if self._unfinished_tasks == 0: | 
					
						
							|  |  |  |                 self._finished.set() | 
					
						
							| 
									
										
										
										
											2024-04-09 00:50:54 +10:00
										 |  |  |         # All getters need to re-check queue-empty to raise ShutDown | 
					
						
							| 
									
										
										
										
											2024-04-07 00:27:13 +10:00
										 |  |  |         while self._getters: | 
					
						
							|  |  |  |             getter = self._getters.popleft() | 
					
						
							|  |  |  |             if not getter.done(): | 
					
						
							|  |  |  |                 getter.set_result(None) | 
					
						
							|  |  |  |         while self._putters: | 
					
						
							|  |  |  |             putter = self._putters.popleft() | 
					
						
							|  |  |  |             if not putter.done(): | 
					
						
							|  |  |  |                 putter.set_result(None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PriorityQueue(Queue): | 
					
						
							|  |  |  |     """A subclass of Queue; retrieves entries in priority order (lowest first).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Entries are typically tuples of the form: (priority number, data). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _init(self, maxsize): | 
					
						
							|  |  |  |         self._queue = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _put(self, item, heappush=heapq.heappush): | 
					
						
							|  |  |  |         heappush(self._queue, item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get(self, heappop=heapq.heappop): | 
					
						
							|  |  |  |         return heappop(self._queue) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class LifoQueue(Queue): | 
					
						
							|  |  |  |     """A subclass of Queue that retrieves most recently added entries first.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _init(self, maxsize): | 
					
						
							|  |  |  |         self._queue = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _put(self, item): | 
					
						
							|  |  |  |         self._queue.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get(self): | 
					
						
							|  |  |  |         return self._queue.pop() |