<html><head></head><body>Thanks Phil, now I understand!<br>
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.<br>
<br><br><div class="gmail_quote"><br>
<br>
Phil Connell <pconnell@gmail.com> schrieb:<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail">On Sat, Nov 23, 2013 at 09:30:29PM +0100, Tobias M. wrote:<br /><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;">Now putting this into a PeriodicTask class that provides a similar interface<br />like our callback version, I get:<br /><br /><br />import asyncio<br /><br />class PeriodicTask2(object):<br /><br />def __init__(self, func, interval):<br />self.func = func<br />self.interval = interval<br />self._loop = asyncio.get_event_loop()<br /><br />def start(self):<br />self.loop.run_until_complete(asyncio.Task(self._run()))<br /><br />@asyncio.coroutine<br />def _run(self):<br />while True:<br />yield from asyncio.sleep(self.interval)<br />self.func()<br /><br /><br />I don't know if I misunderstood anything, but as a user of this class I am<br />not able to run two task simultaneously because start() will block. In the<br />callback version I could instanciate two PeriodicTasks and run them both at<br />the same time (after a call to loop.run_forever()), which is actually what I<br />wanted to achieve with this class.</blockquote><br />You need to separate out creating tasks from running the event loop.<br /><br />Specifically, you should run the event loop in exactly one place, probably at<br />the top level of your script.<br /><br /><br />A toy example:<br /><br />import asyncio<br /><br />@asyncio.coroutine<br />def adder(*args, delay):<br />yield from asyncio.sleep(delay)<br />print(sum(args))<br /><br />def main():<br />asyncio.Task(adder(1, 2, 3, delay=5))<br />asyncio.Task(adder(10, 20, delay=3))<br /><br />loop = asyncio.get_event_loop()<br />loop.run_forever()<br /><br />if __name__ == "__main__":<br />main()<br /><br /><br />$ ./python <a href="http://test.py">test.py</a><br />30<br />6<br /><br /><br />Note that run_forever() will block indefinitely (as the name suggests :). This<br />is generally what you'll want for a long-running server.<br /><br />If you want do something more like:<br />- Spawn some tasks<br />- Run the event loop until they're done<br />- Exit<br /><br />then you'll need to use loop.run_until_complete(asyncio.gather(*tasks))<br />instead.<br /><br /><br />HTH,<br />Phil<br /><br /></pre></blockquote></div></body></html>