summaryrefslogtreecommitdiff
path: root/mobmonitor
diff options
context:
space:
mode:
authorMatthew Sartori <msartori@chromium.org>2015-07-16 17:46:57 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-17 20:39:21 +0000
commit6c8a2c9b5298fc506378272930aac6855d199f26 (patch)
tree97026039f0efe57b8c38ee404c8189d949196d6f /mobmonitor
parentf2a2c448be5733225a9ffd5033c68957ce60ebe6 (diff)
downloadchromite-6c8a2c9b5298fc506378272930aac6855d199f26.tar.gz
mobmonitor: Caching sytem information objects.
This CL adds functionality for check files to access cached versions of the system information class objects. Object instances are cached by their update interval. BUG=chromium:501955 TEST=Unittests. Change-Id: I996e1d64e44026322d30f40eb3e037022e196257 Reviewed-on: https://chromium-review.googlesource.com/286175 Reviewed-by: Matthew Sartori <msartori@chromium.org> Tested-by: Matthew Sartori <msartori@chromium.org> Commit-Queue: Matthew Sartori <msartori@chromium.org>
Diffstat (limited to 'mobmonitor')
-rw-r--r--mobmonitor/system/systeminfo.py81
-rw-r--r--mobmonitor/system/systeminfo_unittest.py43
2 files changed, 120 insertions, 4 deletions
diff --git a/mobmonitor/system/systeminfo.py b/mobmonitor/system/systeminfo.py
index a53a55004..538435b96 100644
--- a/mobmonitor/system/systeminfo.py
+++ b/mobmonitor/system/systeminfo.py
@@ -21,6 +21,16 @@ On retrieving a new record, the time at which it is collected is stored
in update_times with the record name as key, and the record itself is
stored in resources. Every subsequent collection returns what is stored
in the resources dict until the record goes stale.
+
+Users should not directly access the system information classes, but
+should instead use the 'getters' (ie. GetCpu, GetDisk, GetMemory) defined
+at the bottom of this file.
+
+Each of these getters is decorated with the CacheInfoClass decorator.
+This decorator caches instances of each storage class by the specified
+update interval. With this, multiple checkfiles can access the same
+information class instance, which can help to reduce additional and
+redundant system checks being performed.
"""
from __future__ import print_function
@@ -38,6 +48,11 @@ SYSTEMFILE_PROC_FILESYSTEMS = '/proc/filesystems'
SYSTEMFILE_PROC_STAT = '/proc/stat'
+UPDATE_DEFAULT_SEC = 30
+UPDATE_MEMORY_SEC = UPDATE_DEFAULT_SEC
+UPDATE_DISK_SEC = UPDATE_DEFAULT_SEC
+UPDATE_CPU_SEC = 2
+
RESOURCENAME_MEMORY = 'memory'
RESOURCENAME_DISKPARTITIONS = 'diskpartitions'
RESOURCENAME_DISKUSAGE = 'diskusage'
@@ -113,10 +128,53 @@ def CheckStorage(resource_basename):
return func_deco
+def CacheInfoClass(class_name, update_default_sec):
+ """Cache system information class instances by update_sec interval time.
+
+ Args:
+ class_name: The name of the system information class.
+ update_default_sec: The default update interval for this class.
+
+ Returns:
+ The real function decorator.
+ """
+ def func_deco(func):
+ """Return the cached class instance.
+
+ Args:
+ func: The system information class 'getter'.
+
+ Returns:
+ The function wrapper.
+ """
+ cache = {}
+
+ @functools.wraps(func)
+ def wrapper(update_sec=update_default_sec):
+ """Function wrapper for caching system information class objects.
+
+ Args:
+ update_sec: The update interval for the class instance.
+
+ Returns:
+ The cached class instance that has this update interval.
+ """
+ key = '%s:%s' % (class_name, update_sec)
+
+ if key not in cache:
+ cache[key] = func(update_sec=update_sec)
+
+ return cache[key]
+
+ return wrapper
+
+ return func_deco
+
+
class SystemInfoStorage(object):
"""Store and access system information."""
- def __init__(self, update_sec=30):
+ def __init__(self, update_sec=UPDATE_DEFAULT_SEC):
self.update_sec = update_sec
self.update_times = {}
self.resources = {}
@@ -153,7 +211,7 @@ class SystemInfoStorage(object):
class Memory(SystemInfoStorage):
"""Access memory information."""
- def __init__(self, update_sec=30):
+ def __init__(self, update_sec=UPDATE_MEMORY_SEC):
super(Memory, self).__init__(update_sec=update_sec)
@CheckStorage(RESOURCENAME_MEMORY)
@@ -192,7 +250,7 @@ class Memory(SystemInfoStorage):
class Disk(SystemInfoStorage):
"""Access disk information."""
- def __init__(self, update_sec=30):
+ def __init__(self, update_sec=UPDATE_DISK_SEC):
super(Disk, self).__init__(update_sec=update_sec)
@CheckStorage(RESOURCENAME_DISKPARTITIONS)
@@ -268,7 +326,7 @@ class Disk(SystemInfoStorage):
class Cpu(SystemInfoStorage):
"""Access CPU information."""
- def __init__(self, update_sec=2):
+ def __init__(self, update_sec=UPDATE_CPU_SEC):
super(Cpu, self).__init__(update_sec=update_sec)
# CpuLoad depends on having two CpuTime collections at different
@@ -349,3 +407,18 @@ class Cpu(SystemInfoStorage):
cpuloads.append(RESOURCE_CPULOAD(cpu, load))
return cpuloads
+
+
+@CacheInfoClass(Cpu.__name__, UPDATE_CPU_SEC)
+def GetCpu(update_sec=UPDATE_CPU_SEC):
+ return Cpu(update_sec=update_sec)
+
+
+@CacheInfoClass(Memory.__name__, UPDATE_MEMORY_SEC)
+def GetMemory(update_sec=UPDATE_MEMORY_SEC):
+ return Memory(update_sec=update_sec)
+
+
+@CacheInfoClass(Disk.__name__, UPDATE_DISK_SEC)
+def GetDisk(update_sec=UPDATE_DISK_SEC):
+ return Disk(update_sec=update_sec)
diff --git a/mobmonitor/system/systeminfo_unittest.py b/mobmonitor/system/systeminfo_unittest.py
index baa9a2395..d089e10fc 100644
--- a/mobmonitor/system/systeminfo_unittest.py
+++ b/mobmonitor/system/systeminfo_unittest.py
@@ -420,3 +420,46 @@ class Cpu(cros_test_lib.MockTestCase):
self.assertEquals(cpu.resources.get(systeminfo.RESOURCENAME_CPULOADS),
mock_cpuloads)
+
+
+class InfoClassCacheTest(cros_test_lib.MockTestCase):
+ """Unittests for checking that information class caching."""
+
+ def testGetCpu(self):
+ """Test caching explicitly for Cpu information objects."""
+ cpus1 = [systeminfo.GetCpu(), systeminfo.GetCpu(),
+ systeminfo.GetCpu(systeminfo.UPDATE_CPU_SEC),
+ systeminfo.GetCpu(update_sec=systeminfo.UPDATE_CPU_SEC)]
+
+ cpus2 = [systeminfo.GetCpu(10), systeminfo.GetCpu(10),
+ systeminfo.GetCpu(update_sec=10)]
+
+ self.assertTrue(all(id(x) == id(cpus1[0]) for x in cpus1))
+ self.assertTrue(all(id(x) == id(cpus2[0]) for x in cpus2))
+ self.assertTrue(id(cpus1[0]) != id(cpus2[0]))
+
+ def testGetMemory(self):
+ """Test caching explicitly for Memory information objects."""
+ mems1 = [systeminfo.GetMemory(), systeminfo.GetMemory(),
+ systeminfo.GetMemory(systeminfo.UPDATE_MEMORY_SEC),
+ systeminfo.GetMemory(update_sec=systeminfo.UPDATE_MEMORY_SEC)]
+
+ mems2 = [systeminfo.GetMemory(10), systeminfo.GetMemory(10),
+ systeminfo.GetMemory(update_sec=10)]
+
+ self.assertTrue(all(id(x) == id(mems1[0]) for x in mems1))
+ self.assertTrue(all(id(x) == id(mems2[0]) for x in mems2))
+ self.assertTrue(id(mems1[0]) != id(mems2[0]))
+
+ def testGetDisk(self):
+ """Test caching explicitly for Disk information objects."""
+ disks1 = [systeminfo.GetDisk(), systeminfo.GetDisk(),
+ systeminfo.GetDisk(systeminfo.UPDATE_MEMORY_SEC),
+ systeminfo.GetDisk(update_sec=systeminfo.UPDATE_MEMORY_SEC)]
+
+ disks2 = [systeminfo.GetDisk(10), systeminfo.GetDisk(10),
+ systeminfo.GetDisk(update_sec=10)]
+
+ self.assertTrue(all(id(x) == id(disks1[0]) for x in disks1))
+ self.assertTrue(all(id(x) == id(disks2[0]) for x in disks2))
+ self.assertTrue(id(disks1[0]) != id(disks2[0]))