Module infinibatch.closablequeue
Expand source code
from collections import deque
from threading import Condition, Lock, Thread
class ClosedException(Exception):
pass
class ClosableQueue:
"""
A thread-safe queue that can be closed
As long as the the queue is not closed, it behaves just like a thread-safe queue with a capacity limit:
- put blocks until the item can be added
- get blocks until there is an item to be returned
Once the queue is closed, no more items can be added but existing items can be removed:
- put always raises a ClosedException
- get returns an item if the queue is not empty and otherwise raises a ClosedException
"""
def __init__(self, maxsize: int=1000):
self._maxsize = maxsize
self._queue = deque()
self._mutex = Lock()
self._not_empty = Condition(self._mutex)
self._not_full = Condition(self._mutex)
self._closed = False
def put(self, item):
with self._not_full:
if self._closed:
raise ClosedException('This queue has been closed, no more items can be added.')
while len(self._queue) >= self._maxsize:
self._not_full.wait()
if self._closed:
raise ClosedException('This queue has been closed, no more items can be added.')
self._queue.append(item)
self._not_empty.notify()
def get(self):
with self._not_empty:
if self._closed and len(self._queue) == 0:
raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.')
while len(self._queue) == 0:
self._not_empty.wait()
if self._closed and len(self._queue) == 0:
raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.')
item = self._queue.popleft()
self._not_full.notify()
return item
def close(self):
with self._mutex:
self._closed = True
self._not_empty.notify_all()
self._not_full.notify_all()
Classes
class ClosedException (...)-
Common base class for all non-exit exceptions.
Expand source code
class ClosedException(Exception): passAncestors
- builtins.Exception
- builtins.BaseException
class ClosableQueue (maxsize: int = 1000)-
A thread-safe queue that can be closed
As long as the the queue is not closed, it behaves just like a thread-safe queue with a capacity limit: - put blocks until the item can be added - get blocks until there is an item to be returned
Once the queue is closed, no more items can be added but existing items can be removed: - put always raises a ClosedException - get returns an item if the queue is not empty and otherwise raises a ClosedException
Expand source code
class ClosableQueue: """ A thread-safe queue that can be closed As long as the the queue is not closed, it behaves just like a thread-safe queue with a capacity limit: - put blocks until the item can be added - get blocks until there is an item to be returned Once the queue is closed, no more items can be added but existing items can be removed: - put always raises a ClosedException - get returns an item if the queue is not empty and otherwise raises a ClosedException """ def __init__(self, maxsize: int=1000): self._maxsize = maxsize self._queue = deque() self._mutex = Lock() self._not_empty = Condition(self._mutex) self._not_full = Condition(self._mutex) self._closed = False def put(self, item): with self._not_full: if self._closed: raise ClosedException('This queue has been closed, no more items can be added.') while len(self._queue) >= self._maxsize: self._not_full.wait() if self._closed: raise ClosedException('This queue has been closed, no more items can be added.') self._queue.append(item) self._not_empty.notify() def get(self): with self._not_empty: if self._closed and len(self._queue) == 0: raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.') while len(self._queue) == 0: self._not_empty.wait() if self._closed and len(self._queue) == 0: raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.') item = self._queue.popleft() self._not_full.notify() return item def close(self): with self._mutex: self._closed = True self._not_empty.notify_all() self._not_full.notify_all()Methods
def put(self, item)-
Expand source code
def put(self, item): with self._not_full: if self._closed: raise ClosedException('This queue has been closed, no more items can be added.') while len(self._queue) >= self._maxsize: self._not_full.wait() if self._closed: raise ClosedException('This queue has been closed, no more items can be added.') self._queue.append(item) self._not_empty.notify() def get(self)-
Expand source code
def get(self): with self._not_empty: if self._closed and len(self._queue) == 0: raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.') while len(self._queue) == 0: self._not_empty.wait() if self._closed and len(self._queue) == 0: raise ClosedException('This queue has been closed and is empty, no more items can be retrieved.') item = self._queue.popleft() self._not_full.notify() return item def close(self)-
Expand source code
def close(self): with self._mutex: self._closed = True self._not_empty.notify_all() self._not_full.notify_all()