Home | History | Annotate | Download | only in harness
      1 # Copyright (C) 2016 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 '''Timer utility'''
     16 
     17 from __future__ import absolute_import
     18 
     19 import threading
     20 
     21 
     22 class Timer(object):
     23     '''A Timer utility to execute a callback after a certain interval.'''
     24 
     25     def __init__(self, interval, callback):
     26         '''Initialise the Timer without starting it.
     27 
     28         Args:
     29             interval: int or float, interval in seconds to count, before
     30                 invoking the callback
     31             callback: function, it handles the function to call once
     32                 the timeout expires.
     33         '''
     34 
     35         # validate input parameters
     36         if not isinstance(interval, (int, float)):
     37             raise TypeError('Argument "interval" is not a number: '
     38                              '{0}'.format(type(interval)))
     39         if not callable(callback):
     40             raise TypeError('Argument "callback" is not a function: '
     41                              '{0}'.format(type(callback)))
     42 
     43         self._timer = None
     44         self._callback = callback
     45         self._interval = interval
     46 
     47     def _is_running(self):
     48         '''Checks whether the timer is executing.
     49 
     50         Returns:
     51             boolean, true if the timer is currently running, false otherwise
     52         '''
     53         return self._timer is not None
     54 
     55     def start(self):
     56         '''Starts the timer.
     57 
     58         Returns:
     59             self, the Timer instance
     60 
     61         Throws:
     62             RuntimeError: if the timer is already running
     63         '''
     64         if self._is_running():
     65             raise RuntimeError('Timer already running')
     66 
     67         self._timer = threading.Timer(self._interval, self._callback)
     68         self._timer.start()
     69         return self # so that we can perform Timer(...).start()
     70 
     71     def stop(self):
     72         '''Stops the timer if it's executing.
     73 
     74         Returns:
     75             self, the Timer instance
     76         '''
     77 
     78         if self._is_running():
     79             self._timer.cancel()
     80             self._timer = None
     81         return self
     82 
     83     def reset(self):
     84         '''Restart the timer.
     85 
     86         Returns:
     87             self, the Timer instance
     88         '''
     89 
     90         self.stop()
     91         self.start()
     92         return self
     93