Access all elements in asyncio.Queue without removing them

Viewed 556

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, repeat qsize() times. Return the list.
  • appendleft: Queue element. Then remove and append qsize() - 1 elements 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?

0 Answers
Related