2018-03-27 14:30:46 -04:00
|
|
|
"""Extension to the Queue.Queue class.
|
2015-05-08 14:20:43 -04:00
|
|
|
|
|
|
|
|
Added support for the join() method to take a timeout. This is necessary
|
|
|
|
|
in order for KeyboardInterrupt exceptions to get propagated.
|
|
|
|
|
|
|
|
|
|
See https://bugs.python.org/issue1167930 for more details.
|
|
|
|
|
"""
|
|
|
|
|
|
2019-02-19 10:50:57 -05:00
|
|
|
import queue as _queue
|
2015-05-08 14:20:43 -04:00
|
|
|
import time
|
2023-08-03 02:17:04 +00:00
|
|
|
from typing import Generic, TypeVar
|
2015-05-08 14:20:43 -04:00
|
|
|
|
|
|
|
|
# Exception that is raised when get_nowait() is called on an empty Queue.
|
2022-09-02 21:56:05 +00:00
|
|
|
Empty = _queue.Empty
|
2015-05-08 14:20:43 -04:00
|
|
|
|
2024-05-16 18:00:17 -04:00
|
|
|
T = TypeVar("T")
|
2015-05-08 14:20:43 -04:00
|
|
|
|
2023-08-03 02:17:04 +00:00
|
|
|
|
|
|
|
|
class Queue(_queue.Queue, Generic[T]):
|
2018-03-27 14:30:46 -04:00
|
|
|
"""A multi-producer, multi-consumer queue."""
|
2015-05-08 14:20:43 -04:00
|
|
|
|
2025-02-06 08:51:47 -08:00
|
|
|
def join(self, timeout=None):
|
2018-03-27 14:30:46 -04:00
|
|
|
"""Wait until all items in the queue have been processed or 'timeout' seconds have passed.
|
2015-05-08 14:20:43 -04:00
|
|
|
|
|
|
|
|
The count of unfinished tasks is incremented whenever an item is added
|
|
|
|
|
to the queue. The count is decremented whenever task_done() is called
|
|
|
|
|
to indicate that all work on the retrieved item was completed.
|
|
|
|
|
|
|
|
|
|
When the number of unfinished tasks reaches zero, True is returned.
|
|
|
|
|
If the number of unfinished tasks remains nonzero after 'timeout'
|
|
|
|
|
seconds have passed, then False is returned.
|
|
|
|
|
"""
|
|
|
|
|
with self.all_tasks_done:
|
|
|
|
|
if timeout is None:
|
|
|
|
|
while self.unfinished_tasks:
|
|
|
|
|
self.all_tasks_done.wait()
|
|
|
|
|
elif timeout < 0:
|
|
|
|
|
raise ValueError("timeout must be a nonnegative number")
|
|
|
|
|
else:
|
|
|
|
|
# Pass timeout down to lock acquisition
|
|
|
|
|
deadline = time.time() + timeout
|
|
|
|
|
while self.unfinished_tasks:
|
|
|
|
|
remaining = deadline - time.time()
|
|
|
|
|
if remaining <= 0.0:
|
|
|
|
|
return False
|
|
|
|
|
self.all_tasks_done.wait(remaining)
|
|
|
|
|
return True
|