Periodic execution with asyncio

Tobias M. tm at tobix.eu
Tue Nov 26 11:35:26 EST 2013


Thanks Phil, now I understand!
I wasn't aware of the fact that tasks are automatically attached to the event loop when they are created via their constructor. I thought I have to pass them to a run_* method explicitly.




Phil Connell <pconnell at gmail.com> schrieb:
>On Sat, Nov 23, 2013 at 09:30:29PM +0100, Tobias M. wrote:
>> Now putting this into a PeriodicTask class that provides a similar
>interface
>> like our callback version, I get:
>> 
>> 
>> import asyncio
>> 
>> class PeriodicTask2(object):
>> 
>>      def __init__(self, func, interval):
>>          self.func = func
>>          self.interval = interval
>>          self._loop = asyncio.get_event_loop()
>> 
>>      def start(self):
>>          self.loop.run_until_complete(asyncio.Task(self._run()))
>> 
>>     @asyncio.coroutine
>>      def _run(self):
>>          while True:
>>                 yield from asyncio.sleep(self.interval)
>>                 self.func()
>> 
>> 
>> I don't know if I misunderstood anything, but as a user of this class
>I am
>> not able to run two task simultaneously because start() will block.
>In the
>> callback version I could instanciate two PeriodicTasks and run them
>both at
>> the same time (after a call to loop.run_forever()), which is actually
>what I
>> wanted to achieve with this class.
>
>You need to separate out creating tasks from running the event loop.
>
>Specifically, you should run the event loop in exactly one place,
>probably at
>the top level of your script.
>
>
>A toy example:
>
>import asyncio
>
>@asyncio.coroutine
>def adder(*args, delay):
>    yield from asyncio.sleep(delay)
>    print(sum(args))
>
>def main():
>    asyncio.Task(adder(1, 2, 3, delay=5))
>    asyncio.Task(adder(10, 20, delay=3))
>
>    loop = asyncio.get_event_loop()
>    loop.run_forever()
>
>if __name__ == "__main__":
>    main()
>
>
>$ ./python test.py
>30
>6
>
>
>Note that run_forever() will block indefinitely (as the name suggests
>:). This
>is generally what you'll want for a long-running server.
>
>If you want do something more like:
>    - Spawn some tasks
>    - Run the event loop until they're done
>    - Exit
>
>then you'll need to use loop.run_until_complete(asyncio.gather(*tasks))
>instead.
>
>
>HTH,
>Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20131126/4ebcd5d5/attachment.html>


More information about the Python-list mailing list