summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander.sulfrian@fu-berlin.de>2016-07-15 20:27:19 +0200
committerAlexander Sulfrian <alexander.sulfrian@fu-berlin.de>2017-03-21 17:26:08 +0100
commit9af8a7ea4b1de56ac6b8800277518e9159fb7dca (patch)
treedabb1feb9997936af289873417dcaed45bd677dd
parent257ba8d92eda8be0a347f3d68b174a2354782578 (diff)
downloadbcfg2-9af8a7ea4b1de56ac6b8800277518e9159fb7dca.tar.gz
bcfg2-9af8a7ea4b1de56ac6b8800277518e9159fb7dca.tar.bz2
bcfg2-9af8a7ea4b1de56ac6b8800277518e9159fb7dca.zip
Server/Plugin: CallableDict is an OnDemandDict without caching
Add a CallableDict (like OnDemandDict, but without caching the results) to have a dict-like class, that can be cached with the client metadata without caching the dynamic values.
-rw-r--r--src/lib/Bcfg2/Server/Plugin/helpers.py62
1 files changed, 46 insertions, 16 deletions
diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py
index 9ef4a2527..762d018eb 100644
--- a/src/lib/Bcfg2/Server/Plugin/helpers.py
+++ b/src/lib/Bcfg2/Server/Plugin/helpers.py
@@ -1700,7 +1700,7 @@ class GroupSpool(Plugin, Generator):
self.handles[reqid] = relative
-class OnDemandDict(MutableMapping):
+class CallableDict(MutableMapping):
""" This maps a set of keys to a set of value-getting functions;
the values are populated on-the-fly by the functions as the values
are needed (and not before). This is for example used by
@@ -1709,32 +1709,27 @@ class OnDemandDict(MutableMapping):
Unlike a dict, you can specify values or functions for the
righthand side of this mapping. If you specify a function, it will
- be evaluated, when you access the value for the first time. E.g.:
+ be evaluated everytime you access the value. E.g.:
.. code-block:: python
- d = OnDemandDict(foo=load_foo,
+ d = CallableDict(foo=load_foo,
bar="bar")
"""
def __init__(self, **getters):
- self._values = dict()
self._getters = dict(**getters)
def __getitem__(self, key):
- if key not in self._values:
- if callable(self._getters[key]):
- self._values[key] = self._getters[key]()
- else:
- self._values[key] = self._getters[key]
-
- return self._values[key]
+ if callable(self._getters[key]):
+ return self._getters[key]()
+ else:
+ return self._getters[key]
def __setitem__(self, key, getter):
self._getters[key] = getter
def __delitem__(self, key):
- del self._values[key]
del self._getters[key]
def __len__(self):
@@ -1743,9 +1738,44 @@ class OnDemandDict(MutableMapping):
def __iter__(self):
return iter(self._getters.keys())
- def __repr__(self):
- rv = dict(self._values)
+ def _current_data(self):
+ """ Return a dict with the current available static data
+ and ``unknown`` for all callable values.
+ """
+ rv = dict()
for key in self._getters.keys():
- if key not in rv:
+ if callable(self._getters[key]):
rv[key] = 'unknown'
- return str(rv)
+ else:
+ rv[key] = self._getters[key]
+ return rv
+
+ def __repr__(self):
+ return str(self._current_data())
+
+
+class OnDemandDict(CallableDict):
+ """ This is like a :class:`CallableDict` but it will cache
+ the results of the callable getters, so that it is only evaluated
+ once when you first access it.
+ """
+
+ def __init__(self, **getters):
+ CallableDict.__init__(self, **getters)
+ self._values = dict()
+
+ def __getitem__(self, key):
+ if key not in self._values:
+ self._values[key] = super(OnDemandDict, self).__getitem__(key)
+ return self._values[key]
+
+ def __delitem__(self, key):
+ super(OnDemandDict, self).__delitem__(key)
+ del self._values[key]
+
+ def _current_data(self):
+ rv = super(OnDemandDict, self)._current_data()
+ for (key, value) in rv.items():
+ if key in self._values:
+ rv[key] = value
+ return rv