From: Tony Asleson Date: Thu, 25 Feb 2016 20:57:12 +0000 (-0600) Subject: lvmdbusd: Reduce unnecessary state refreshes X-Git-Tag: v2_02_144~10 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=f1bc68beb4e493a9c1a52750e99d50f874ca89d9;p=lvm2.git lvmdbusd: Reduce unnecessary state refreshes When we use udev or have lvm call back into the dbus service when a change occurs, even if that change originated from the dbus service we end up refreshing the state of the system twice which is not needed or wanted. This change handles this case by removing any pending refreshes in the worker queue if the state of the system was just updated. Signed-off-by: Tony Asleson --- diff --git a/daemons/lvmdbusd/lvmdb.py b/daemons/lvmdbusd/lvmdb.py index 46e20991e..132bee726 100755 --- a/daemons/lvmdbusd/lvmdb.py +++ b/daemons/lvmdbusd/lvmdb.py @@ -272,10 +272,9 @@ class DataStore(object): :param log Add debug log entry/exit messages :return: None """ - + self.num_refreshes += 1 if log: log_debug("lvmdb - refresh entry") - self.num_refreshes += 1 # Grab everything first then parse it _raw_pvs = cmdhandler.pv_retrieve_with_segs() diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py index c9211f713..6cabcc4ab 100644 --- a/daemons/lvmdbusd/main.py +++ b/daemons/lvmdbusd/main.py @@ -24,11 +24,11 @@ from .manager import Manager from .background import background_reaper import traceback import queue -import sys from . import udevwatch from .utils import log_debug import argparse import os +from .refresh import handle_external_event, event_complete class Lvm(objectmanager.ObjectManager): @@ -36,6 +36,30 @@ class Lvm(objectmanager.ObjectManager): super(Lvm, self).__init__(object_path, BASE_INTERFACE) +def _discard_pending_refreshes(): + # We just handled a refresh, if we have any in the queue they can be + # removed because by definition they are older than the refresh we just did. + # As we limit the number of refreshes getting into the queue + # we should only ever have one to remove. + requests = [] + while not cfg.worker_q.empty(): + try: + r = cfg.worker_q.get(block=False) + if r.method != handle_external_event: + requests.append(r) + else: + # Make sure we make this event complete even though it didn't + # run, otherwise no other events will get processed + event_complete() + break + except queue.Empty: + break + + # Any requests we removed, but did not discard need to be re-queued + for r in requests: + cfg.worker_q.put(r) + + def process_request(): while cfg.run.value != 0: try: @@ -50,16 +74,21 @@ def process_request(): end = cfg.db.num_refreshes - if end - start > 1: - log_debug( - "Inspect method %s for too many refreshes" % - (str(req.method))) + num_refreshes = end - start + + if num_refreshes > 0: + _discard_pending_refreshes() + + if num_refreshes > 1: + log_debug( + "Inspect method %s for too many refreshes" % + (str(req.method))) log_debug("Complete ") except queue.Empty: pass except Exception: - traceback.print_exc(file=sys.stdout) - pass + st = traceback.format_exc() + utils.log_error("process_request exception: \n%s" % st) def main():