0

This might not be a good idea, but can I have await waiting for "dying" of weakref?

Especially, I want to do something like this

from asyncio import losing_ref, wait, create_task
from weakref import ref

async def consumer(queue_ref):
    while queue_ref() is not None:
        await wait(losing_ref(queue_ref), queue_ref().get())
        ...
        
async def producer(queue):
    for i in range(20):
        await queue.put(i)
        
async def main():
    queue = Queue(1)
    create_task(sender(queue))
    create_task(receiver(ref(queue)))
    del queue // make sure `main` is not referencing to it
    ...

The point is like the queue can "close" itself without need of manual notification to the other end, since all reference to it is gone. This would be handy especially when used in a loop where you might have to raise StopAsyncIteration on the producer side manually

ZisIsNotZis
  • 1,570
  • 1
  • 13
  • 30
  • An interesting idea even if I find it a bad design. I would never rely on what the garbage collector does and mainly when it does. Anyway, waiting in `queue.get` will keep the reference alive. Maybe it could work with timeouts and checks between the `queue.get`s. BTW, there was a question about monitoring the regular reference count, but it is unanswered (https://stackoverflow.com/q/47254130/5378816). – VPfB Jan 18 '21 at 08:39
  • I don't think this can work as suggested because the `wait(...)` invocation sends a *strong* reference to the queue to `wait()`, it being embedded in the bound method obtained with `queue_ref().get()`. You could instead emit an event when the producer goes away, and await that event and `queue.get()` using `wait(..., FIRST_COMPLETED)`. Then you can check the producer count and bail out if there are no more producers. – user4815162342 Jan 18 '21 at 10:42

0 Answers0