Pascal de Sélys
Pascal de Sélys

Reputation: 137

TRIO Lib queue get and put

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)

Upvotes: 1

Views: 714

Answers (2)

Hunor Portik
Hunor Portik

Reputation: 78

Since the post is quite old and the pkg has been updated, let me quickly post an myself.

If u've been wondering where the Queue object gone, it become a entity called channel.

Small, well-written example to use it: https://stackoverflow.com/a/75625692/15185021

Upvotes: 0

Nathaniel J. Smith
Nathaniel J. Smith

Reputation: 12722

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

Upvotes: 4

Related Questions