Periodic execution with asyncio
Tobias M.
tm at tobix.eu
Sat Nov 23 15:30:29 EST 2013
Thanks a lot for your helpful posts, Terry!
On 11/23/2013 01:00 AM, Terry Reedy wrote:
> * Make the task function a parameter 'func'.
I actually like subclassing, but yes I know there are some downsides :)
>
> * Rename start to _set to better describe what is does and call it in
> the _run function to not repeat the handler setting line. (If 'start'
> has any magic meaning, I am not aware of it. I am aware that there
> could be situations in which one would want a public method, to be
> called from other handlers. But that would be a different class ;-)
>
> * Comment out the stop method because it is useless in the current
> usage. I believe handler.cancel is only relevant after the handler is
> set and before it is fired. This can only be done from another handler.
You are right, the handler setting line should not be repeated.
I choose start() and stop() for controlling the task because this is an
interface I would instantly understand as a user of this class.
By the way: My whole motivation is, that I want to implement such a task
class in a network library I am currently writing.
On 11/23/2013 02:33 AM, Terry Reedy wrote:
> I was initially baffled also until I managed to assemble all the
> needed pieces.
>
> import asyncio
>
> def f():
> print('Hello World')
>
> @asyncio.coroutine
> def g(func, interval):
> while True:
> yield from asyncio.sleep(interval)
> func()
>
> loop = asyncio.get_event_loop()
>
> try:
> loop.run_until_complete(asyncio.Task(g(f, 2)))
> except KeyboardInterrupt:
> print('Loop stopped')
>
Thanks, now I got it. I just couldn't figure out that I have to yield
from the sleep function.
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.
More information about the Python-list
mailing list