osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problem with coroutines old-style / new-style usage and features


Hi guys.

I am discovering coroutines and asynchronous programming, and I have a little problem with a little example I'm coding myself as an excercice.

Let say you take two guys in the street: Dave and Bryan.
You ask dave to count from 1 to 50, 1 by 1. He will do it fast.
And you ask Bryan to count from 208 to 166 in reversing order, 7 by 7! It will take him some time between each number to think about it.

Now I have a recorder wich is able to recognize voices. I use it to record both of them counting at the same time.

Here is the recorder:


@asyncio.coroutine
def recorder():
    dialog = []
    while True:
        sent = yield dialog
        if sent is not None:
            name, things = sent
            dialog.append(f'{name} says : {things}')


It is storing the dialog, and you can ask him fot it later by sending None to it.

For the calculation, I'm using a ascyn generator:


async def calcul_mental(range_args, name, timeout=0.2):
    for i in range(*range_args):
        await asyncio.sleep(timeout)
        yield name, i


To link the two, I came up with this little coroutine:


async def record(recorder, gen):
    async for name, i in gen:
        recorder.send([name, i])


And my main:


def main():

    g1 = calcul_mental([1, 51],
                       name='Dave',
                       timeout=0.2)

    g2 = calcul_mental([208, 165, -7],
                       name='Bryan',
                       timeout=2)

    r = recorder()
    r.send(None)

    coros = asyncio.gather(record(r, g1), record(r, g2))
    loop = asyncio.get_event_loop()
    loop.run_until_complete(coros)

    dialog = r.send(None)
    for line in dialog:
        print(line)


It works well, but I was wondering if I could turn recorder into a new style coroutine...

The problems are:
- I can't await for an async generator;
- I can't let an await alone to send data to it;
- I can't turn it into an AsyncGenerator because it will lost the .send() method.

I think it's just a problem of design, but I wasn't able to solve it myself.

Any thoughts about it?

Thanks!