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)
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 await
s 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).