summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2018-02-19 13:09:10 -0600
committerMatt Spinler <spinler@us.ibm.com>2018-02-23 13:51:02 -0600
commitc458deea83b4356f07194691e301037d8e831d46 (patch)
treea01904097309523a576612c33cdc2c3a17a69095
parent8bbf9d2cc5a502fa0df0e70bd4232208a1ab6c01 (diff)
downloadphosphor-dbus-monitor-c458deea83b4356f07194691e301037d8e831d46.zip
phosphor-dbus-monitor-c458deea83b4356f07194691e301037d8e831d46.tar.gz
Add oneshot support to count conditions
When a count condition is a oneshot, it will only trigger the callback the first time the condition is true. The condition needs to evaluate to false at least once to rearm the callback. A use case for this would be when a group of properties is being watched for a subset of them hit a certain value. Even though every properties changed signal for every property in the group would check the condition, only the first time the condition is true would the callback be issued. This behavior is specified with a 'oneshot: true' entry in the YAML. If not present, it defaults to false which is the original behavior. Tested: Verify this does indeed do what is advertised by modifying condition rules to consistently pass and checking behavior. Change-Id: Ie185621e86c605234bf329a5f38317267dbb6fb6 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
-rw-r--r--src/count.hpp27
-rw-r--r--src/example/example.yaml8
-rw-r--r--src/example/test.yaml2
-rwxr-xr-xsrc/pdmgen.py3
-rw-r--r--src/templates/count.mako.cpp3
5 files changed, 38 insertions, 5 deletions
diff --git a/src/count.hpp b/src/count.hpp
index f7b809f..51a76eb 100644
--- a/src/count.hpp
+++ b/src/count.hpp
@@ -26,6 +26,9 @@ namespace monitoring
* one. In pass two, apply a second C++ relational operator
* to the number of properties that pass the test from pass one
* to a count provided by the configuration file.
+ *
+ * If the oneshot parameter is true, then this condition won't pass
+ * again until it fails at least once.
*/
template <typename T>
class CountCondition : public IndexedConditional
@@ -41,10 +44,12 @@ class CountCondition : public IndexedConditional
CountCondition(
const PropertyIndex& conditionIndex,
const std::function<bool(size_t)>& _countOp,
- const std::function<bool(T)>& _propertyOp) :
+ const std::function<bool(T)>& _propertyOp,
+ bool oneshot = false) :
IndexedConditional(conditionIndex),
countOp(_countOp),
- propertyOp(_propertyOp) {}
+ propertyOp(_propertyOp),
+ oneshot(oneshot) {}
bool operator()() override
{
@@ -70,7 +75,18 @@ class CountCondition : public IndexedConditional
// *INDENT-ON*
// Now apply the count condition to the count.
- return countOp(count);
+ auto result = countOp(count);
+
+ // If this was a oneshot and the the condition has already
+ // passed, then don't let it pass again until the condition
+ // has gone back to false.
+ if (oneshot && result && lastResult)
+ {
+ return false;
+ }
+
+ lastResult = result;
+ return result;
}
private:
@@ -78,6 +94,11 @@ class CountCondition : public IndexedConditional
std::function<bool(size_t)> countOp;
/** @brief The comparison to perform on each property. */
std::function<bool(T)> propertyOp;
+ /** @brief If the condition can be allowed to pass again
+ on subsequent checks that are also true. */
+ const bool oneshot;
+ /** @brief The result of the previous check. */
+ bool lastResult = false;
};
} // namespace monitoring
} // namespace dbus
diff --git a/src/example/example.yaml b/src/example/example.yaml
index 226f491..bfb1c62 100644
--- a/src/example/example.yaml
+++ b/src/example/example.yaml
@@ -181,7 +181,12 @@
For example, a callback that requires at least three temperature sensors
in the group to be higher than 115 degrees might use a count condition
- with an op of >, a count op of >=, a bound of 115, and a countbound of 3.'
+ with an op of >, a count op of >=, a bound of 115, and a countbound of 3.
+
+ The optional oneshot parameter defaults to false. If it is specified and
+ set to true, then the callback will only be called once for as long as the
+ condition is repeatedly passing. The condition needs to fail at least
+ once to rearm the callback.'
class: condition
condition: count
@@ -192,6 +197,7 @@
countbound: 3
op: '>='
bound: 115
+ oneshot: true
- name: example deferred condition
description: >
diff --git a/src/example/test.yaml b/src/example/test.yaml
index fb37efe..6632891 100644
--- a/src/example/test.yaml
+++ b/src/example/test.yaml
@@ -317,6 +317,7 @@
countbound: 3
op: '<'
bound: 115
+ oneshot: true
- name: test count lte
class: condition
@@ -329,6 +330,7 @@
countbound: 3
op: '<='
bound: 115
+ oneshot: false
- name: test count gt
class: condition
diff --git a/src/pdmgen.py b/src/pdmgen.py
index fe3f826..7487015 100755
--- a/src/pdmgen.py
+++ b/src/pdmgen.py
@@ -645,6 +645,9 @@ class CountCondition(Condition, Renderer):
self.countbound = kw.pop('countbound')
self.op = kw.pop('op')
self.bound = kw.pop('bound')
+ self.oneshot = TrivialArgument(
+ type='boolean',
+ value=kw.pop('oneshot', False))
super(CountCondition, self).__init__(**kw)
def setup(self, objs):
diff --git a/src/templates/count.mako.cpp b/src/templates/count.mako.cpp
index 9ac9c3c..f4b4c8f 100644
--- a/src/templates/count.mako.cpp
+++ b/src/templates/count.mako.cpp
@@ -1,4 +1,5 @@
std::make_unique<CountCondition<${c.datatype}>>(
${indent(1)}ConfigPropertyIndicies::get()[${c.instances}],
${indent(1)}[](const auto& item){return item ${c.countop} ${c.countbound};},
-${indent(1)}[](const auto& item){return item ${c.op} ${c.bound.argument(loader, indent=indent +1)};})\
+${indent(1)}[](const auto& item){return item ${c.op} ${c.bound.argument(loader, indent=indent +1)};},
+${indent(1)}${c.oneshot.argument(loader, indent=indent +1)})\
OpenPOWER on IntegriCloud