From 4be39bf9859bab05a6cb61bf7d6145dc267367de Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 4 Aug 2012 17:13:20 +0000 Subject: [PATCH] Replace those complicated wait construct by a efficient Timer class. Timer is a low-resolution timeout system that lets us have long timeouts very energy-efficient and interuptable. --- collecty/__init__.py | 12 ++++---- collecty/plugins/__init__.py | 2 ++ collecty/plugins/base.py | 54 +++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/collecty/__init__.py b/collecty/__init__.py index 5e684f4..b7e1f22 100644 --- a/collecty/__init__.py +++ b/collecty/__init__.py @@ -47,14 +47,13 @@ class Collecty(object): # The default interval, when all data is written to disk. SUBMIT_INTERVAL = 300 - HEARTBEAT = 2 - def __init__(self): self.config = configparser.ConfigParser() self.instances = [] # Indicates whether this process should be running or not. self.running = True + self.timer = plugins.Timer(self.SUBMIT_INTERVAL, heartbeat=2) # Add all automatic plugins. self.add_autocreate_plugins() @@ -110,14 +109,11 @@ class Collecty(object): i.start() # Regularly submit all data to disk. - counter = self.SUBMIT_INTERVAL / self.HEARTBEAT while self.running: - time.sleep(self.HEARTBEAT) - counter -= 1 + self.timer.reset() - if counter == 0: + if self.timer.wait(): self.submit_all() - counter = self.SUBMIT_INTERVAL / self.HEARTBEAT # Wait until all instances are finished. while self.instances: @@ -142,6 +138,8 @@ class Collecty(object): log.debug(_("Received shutdown signal")) self.running = False + if self.timer: + self.timer.cancel() # Propagating shutdown to all threads. for i in self.instances: diff --git a/collecty/plugins/__init__.py b/collecty/plugins/__init__.py index a8af815..71cf971 100644 --- a/collecty/plugins/__init__.py +++ b/collecty/plugins/__init__.py @@ -19,6 +19,8 @@ # # ############################################################################### +from base import Timer + import cpu import loadavg import memory diff --git a/collecty/plugins/base.py b/collecty/plugins/base.py index 472a3a0..e85653e 100644 --- a/collecty/plugins/base.py +++ b/collecty/plugins/base.py @@ -28,6 +28,34 @@ import time from ..constants import * from ..i18n import _ +class Timer(object): + def __init__(self, timeout, heartbeat=1): + self.timeout = timeout + self.heartbeat = heartbeat + + self.reset() + + def reset(self): + # Save start time. + self.start = time.time() + + # Has this timer been killed? + self.killed = False + + @property + def elapsed(self): + return time.time() - self.start + + def cancel(self): + self.killed = True + + def wait(self): + while self.elapsed < self.timeout and not self.killed: + time.sleep(self.heartbeat) + + return self.elapsed > self.timeout + + class Plugin(threading.Thread): # The name of this plugin. name = None @@ -56,10 +84,6 @@ class Plugin(threading.Thread): self.log = logging.getLogger("collecty.plugins.%s" % self.name) self.log.propagate = 1 - # Keepalive options - self.heartbeat = 2 - self.running = True - self.data = [] # Create the database file. @@ -68,6 +92,10 @@ class Plugin(threading.Thread): # Run some custom initialization. self.init() + # Keepalive options + self.running = True + self.timer = Timer(self.interval) + self.log.info(_("Successfully initialized.")) def __repr__(self): @@ -164,19 +192,15 @@ class Plugin(threading.Thread): def run(self): self.log.debug(_("Started.")) - counter = 0 while self.running: - if counter == 0: + # Reset the timer. + self.timer.reset() + + # Wait until the timer has successfully elapsed. + if self.timer.wait(): self.log.debug(_("Collecting...")) self._read() - self.log.debug(_("Sleeping for %.4fs.") % self.interval) - - counter = self.interval / self.heartbeat - - time.sleep(self.heartbeat) - counter -= 1 - self._submit() self.log.debug(_("Stopped.")) @@ -184,6 +208,10 @@ class Plugin(threading.Thread): self.log.debug(_("Received shutdown signal.")) self.running = False + # Kill any running timers. + if self.timer: + self.timer.cancel() + @property def now(self): """ -- 2.39.2