I'm working on a program that uses a asyncio.Queue. It would be nice to be able to clear the queue, access all queued elements without removing them, and to insert elements at "index 1" in the queue.
I know, this sounds like a collections.deque, but I rely on async/await code (i.e. blocking get).
My approach:
clear: Remove all elements from the queue until it's empty.get_all: Remove element, add to list, queue element again, repeatqsize()times. Return the list.appendleft: Queue element. Then remove and appendqsize() - 1elements from/to queue until
class BlockingDeque(asyncio.Queue):
def clear(self):
while not self.empty():
self.get_nowait()
self.task_done()
def get_all(self):
all = []
for i in range(self.qsize()):
item = self.get_nowait()
self.task_done()
self.put_nowait(item)
all.append(item)
return all
async def appendleft(self, item):
await self.put(item)
for _ in range(self.qsize() - 1):
item = self.get_nowait()
self.task_done()
self.put_nowait(item)
I also came across this solution, which accesses asyncio.Queue().__dict__['_queue'].
class BlockingDeque(asyncio.Queue):
def clear(self):
self._queue.clear()
def get_all(self):
return self._queue.copy()
def appendleft(self, x):
self._queue.appendleft(x)
Which approach is preferable? Is there a better way of doing it?