Asynchronous iterator ticks at regular intervals

I am using an asynchronous iterator that will be used with async for, which should return a new value in the (mostly) regular interval.

We can illustrate such an iterator with a simple clock that will increment the counter every ~ n seconds:

import asyncio

class Clock(object):
    def __init__(self, interval=1):
        self.counter = 0
        self.interval = interval
        self.tick = asyncio.Event()
        asyncio.ensure_future(self.tick_tock())

    async def tick_tock(self):
        while True:
            self.tick.clear()
            await asyncio.sleep(self.interval)
            self.counter = self.__next__()
            self.tick.set()

    def __next__(self):
        self.counter += 1
        return self.counter

    def __aiter__(self):
        return self

    async def __anext__(self):
        await self.tick.wait()
        return self.counter

Is there a better or cleaner approach than using asyncio.Event? There will be async formore than one coroutine on this iterator .

+4
source share
2 answers

I think your approach is fine. Note that with python 3.6 you can also use asynchronous generators :

async def clock(start=0, step=1, interval=1.):
    for i in count(start, step):
        yield i
        await asyncio.sleep(interval)

. , , . .

+1

Python 3.6+, , .

async def Clock(interval=1):
    counter = 0
    while True:
        await asyncio.sleep(interval)
        counter += 1
        yield counter


async def main():
    async for i in Clock(1):
        print(i)
        if i == 4:
            break


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()
0

Source: https://habr.com/ru/post/1688160/


All Articles