0

Hello I'm trying to use trio with two asyncronous functions and a message in between. but it doesn't launch the consumer and I don't really understand why . The producer sends well in the'queue' and does not send anything once it is saturated. But the consumer doesn't go for it. Or am I making a mistake? Thank you in advance

import time

import trio
async def producer(queue):
    while True:
        time.sleep(1)
        if queue.full() is False:
            queue.put_nowait(1)
            print(queue.full())
            print('put')

async def consumer(queue):
    while True:
        time.sleep(4)
        if queue.full() is True:
            print(queue.get_nowait())
            print(queue.full())
        print('get')

async def main():

    queue = trio.Queue(capacity=4)
    async with trio.open_nursery() as nursery:
        # Two producers
        nursery.start_soon(consumer, queue)
        nursery.start_soon(producer, queue)

trio.run(main)
Nathaniel J. Smith
  • 9,038
  • 4
  • 35
  • 46

1 Answers1

3

Your problem is that you're using time.sleep. If you replace both of the calls to time.sleep(...) with calls to await trio.sleep(...), then your example works.

Trio, like all async libraries, can only switch between tasks at places where you use await. This means that you should never use blocking synchronous functions like time.sleep – instead you need to use the asynchronous versions that Trio provides, like trio.sleep. In your code, you don't have any awaits at all, so whichever task happens to run first will keep running forever, and never give the other task a chance to run.

The Trio tutorial has more details on this.

It is unfortunate that Trio doesn't notice this and give you some kind of warning... I just filed an issue to hopefully add that.

Also, FYI, your way of working with the queue is probably making things more complicated than they need to be :-). I don't think I ever use queue.full(), and put_nowait and get_nowait have some legitimate uses but they're fairly rare. For most purposes, the only things you need to call are await queue.put(value) and value = await queue.get() (or print(await queue.get()), or whatever).

Nathaniel J. Smith
  • 9,038
  • 4
  • 35
  • 46