Adding threading.RepeatTimer class
We have a threading.Timer class which executes after a given delay and then terminates. I was thinking about a pre-made class that would execute, wait an interval, and then repeat. It would cut down on the logic people need to implement themselves, and make simple scripts faster. Here are some use cases: # Send a ping message to all connected clients every 120 seconds from server import ping_all_clients pinger = threading.RepeatTimer(120, ping_all_clients) pinger.start() # Check for updates every 3 hours from mymodule import check_for_updates update_checker = threading.RepeatTimer(60*60*3, check_for_updates) update_checker.start() I was thinking of the class having an initializer signature as follows: class threading.RepeatTimer(interval, function, args=[], kwargs={}, limit=None) Create a timer that will run function with args and kwargs and repeat every interval secods. If limit is an integer, limits repetitions to that many calls. cancel() Stop the repeat timer. If in the middle of a call, the call is allowed to finish. Daniel
On Thu, Jan 27, 2011 at 12:03, Daniel da Silva <ddasilva@umd.edu> wrote:
We have a threading.Timer class which executes after a given delay and then terminates. I was thinking about a pre-made class that would execute, wait an interval, and then repeat. It would cut down on the logic people need to implement themselves, and make simple scripts faster.
Here are some use cases:
# Send a ping message to all connected clients every 120 seconds from server import ping_all_clients pinger = threading.RepeatTimer(120, ping_all_clients) pinger.start()
# Check for updates every 3 hours from mymodule import check_for_updates update_checker = threading.RepeatTimer(60*60*3, check_for_updates) update_checker.start()
I was thinking of the class having an initializer signature as follows:
class threading.RepeatTimer(interval, function, args=[], kwargs={}, limit=None) Create a timer that will run function with args and kwargs and repeat every interval secods. If limit is an integer, limits repetitions to that many calls.
cancel() Stop the repeat timer. If in the middle of a call, the call is allowed to finish.
Daniel
I'm not sure this is a good fit in the standard library. There's too much that the implementer might want to customize for their repeating needs. For your pinger, what if a ping fails? Keep pinging while it fails? Timeout for a bit and try again? Increasing timeouts? Just exit? I don't think there's a general enough use case that a repetitive timer has in order to be included. The following will likely do what you want. import threading class RepeatTimer(threading.Thread): def __init__(self, interval, callable, *args, **kwargs): threading.Thread.__init__(self) self.interval = interval self.callable = callable self.args = args self.kwargs = kwargs self.event = threading.Event() self.event.set() def run(self): while self.event.is_set(): t = threading.Timer(self.interval, self.callable, self.args, self.kwargs) t.start() t.join() def cancel(self): self.event.clear()
Am 27.01.2011 23:12, schrieb Brian Curtin:
import threading
class RepeatTimer(threading.Thread): def __init__(self, interval, callable, *args, **kwargs): threading.Thread.__init__(self) self.interval = interval self.callable = callable self.args = args self.kwargs = kwargs self.event = threading.Event() self.event.set()
def run(self): while self.event.is_set(): t = threading.Timer(self.interval, self.callable, self.args, self.kwargs) t.start() t.join()
def cancel(self): self.event.clear()
CherryPy has two simpler implementations for a PerpetualTimer and a BackgroundTask: http://cherrypy.org/browser/trunk/cherrypy/process/plugins.py#L424 . The BackgroundTask is less CPU consuming under Python 2.x. I guess the extended threading funtions in 3.2 make the implementation obsolete. Christian
27.01.2011 20:03, Daniel da Silva kirjoitti:
We have a threading.Timer class which executes after a given delay and then terminates. I was thinking about a pre-made class that would execute, wait an interval, and then repeat. It would cut down on the logic people need to implement themselves, and make simple scripts faster. For that purpose you can use APScheduler's interval scheduling: http://packages.python.org/APScheduler/
Granted, it's not a part of the standard library but it would fulfill the purpose stated above.
Here are some use cases:
# Send a ping message to all connected clients every 120 seconds from server import ping_all_clients pinger = threading.RepeatTimer(120, ping_all_clients) pinger.start()
# Check for updates every 3 hours from mymodule import check_for_updates update_checker = threading.RepeatTimer(60*60*3, check_for_updates) update_checker.start()
I was thinking of the class having an initializer signature as follows:
class threading.RepeatTimer(interval, function, args=[], kwargs={}, limit=None) Create a timer that will run function with args and kwargs and repeat every interval secods. If limit is an integer, limits repetitions to that many calls.
cancel() Stop the repeat timer. If in the middle of a call, the call is allowed to finish.
Daniel
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
participants (4)
-
Alex Grönholm
-
Brian Curtin
-
Christian Heimes
-
Daniel da Silva