Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timer cannot restart after it is being stopped in Python

I am using Python 2.7. I have a timer that keeps repeating a timer callback action until it has been stopped. It uses a Timer object. The problem is that after it has been stopped, it cannot be restarted. The Timer object code is as follows;

from threading import Timer

class RepeatingTimer(object):
    def __init__(self,interval, function, *args, **kwargs):
        super(RepeatingTimer, self).__init__()
        self.args = args
        self.kwargs = kwargs
        self.function = function
        self.interval = interval

    def start(self):
        self.callback()

    def stop(self):
        self.interval = False       

    def callback(self):
        if self.interval:
            self.function(*self.args, **self.kwargs)
            Timer(self.interval, self.callback, ).start()

To start the timer, the code below is run;

repeat_timer = RepeatingTimer(interval_timer_sec, timer_function, arg1, arg2)
repeat_timer.start()    

To stop the timer, the code is;

repeat_timer.stop() 

After it is stopped, I tried to restart the timer by calling repeat_timer.start() but the timer is unable to start. How can the timer be made to restart after it has been stopped?

Thank you.

like image 452
guagay_wk Avatar asked Jun 06 '14 01:06

guagay_wk


2 Answers

Here is a corrected version:

from __future__ import print_function


from threading import Timer


def hello():
    print("Hello World!")


class RepeatingTimer(object):

    def __init__(self, interval, f, *args, **kwargs):
        self.interval = interval
        self.f = f
        self.args = args
        self.kwargs = kwargs

        self.timer = None

    def callback(self):
        self.f(*self.args, **self.kwargs)
        self.start()

    def cancel(self):
        self.timer.cancel()

    def start(self):
        self.timer = Timer(self.interval, self.callback)
        self.timer.start()


t = RepeatingTimer(3, hello)
t.start()

Example Run:

$ python -i foo.py
>>> Hello World!

>>> Hello World!

>>> t.cancel()
like image 132
James Mills Avatar answered Sep 24 '22 19:09

James Mills


The reason your timer is not restarting is because you never reset self.interval to True before trying to restart the timer. However, if that's the only change you make, you will find your timer is vulnerable to a race condition that will result in more than one timer running concurrently.

like image 32
Brionius Avatar answered Sep 26 '22 19:09

Brionius