diff options
author | Matthew Sartori <msartori@chromium.org> | 2015-07-16 17:46:57 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-17 20:39:21 +0000 |
commit | 6c8a2c9b5298fc506378272930aac6855d199f26 (patch) | |
tree | 97026039f0efe57b8c38ee404c8189d949196d6f /mobmonitor | |
parent | f2a2c448be5733225a9ffd5033c68957ce60ebe6 (diff) | |
download | chromite-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.py | 81 | ||||
-rw-r--r-- | mobmonitor/system/systeminfo_unittest.py | 43 |
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])) |