PolicyManager: Schedule re-evaluations based on variable usage.
This patch makes the EvaluationContext re-schedule a policy request
based on the variables used by that method, waiting for the Async
variables and polling the Poll variables on the suggested interval.
In order to use the main loop functions from the EvaluationContext
they were moved to its own file called event_loop.h.
BUG=chromium:340871
TEST=Unit tests added.
Change-Id: Ibfc52e4dfd12c5e1ef87b5ad9cc318f9821dcfdd
Reviewed-on: https://chromium-review.googlesource.com/190424
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/policy_manager/evaluation_context.h b/policy_manager/evaluation_context.h
index 27998d6..9e8b3c2 100644
--- a/policy_manager/evaluation_context.h
+++ b/policy_manager/evaluation_context.h
@@ -7,19 +7,25 @@
#include <map>
+#include <base/callback.h>
#include <base/memory/ref_counted.h>
+#include <base/time.h>
-#include "update_engine/policy_manager/variable.h"
#include "update_engine/policy_manager/boxed_value.h"
+#include "update_engine/policy_manager/event_loop.h"
+#include "update_engine/policy_manager/variable.h"
namespace chromeos_policy_manager {
// The EvaluationContext class is the interface between a policy implementation
// and the state. The EvaluationContext tracks the variables used by a policy
// request and caches the returned values, owning those cached values.
-class EvaluationContext : public base::RefCounted<EvaluationContext> {
+class EvaluationContext :
+ public base::RefCounted<EvaluationContext>,
+ private BaseVariable::ObserverInterface {
public:
EvaluationContext() {}
+ ~EvaluationContext();
// Returns a pointer to the value returned by the passed variable |var|. The
// EvaluationContext instance keeps the ownership of the returned object. The
@@ -30,7 +36,30 @@
template<typename T>
const T* GetValue(Variable<T>* var);
+ // Schedules the passed |callback| closure to be called when a cached
+ // variable changes its value or a polling interval passes. If none of these
+ // events can happen, for example if there's no cached variable, this method
+ // returns false.
+ //
+ // Right before the passed closure is called the EvaluationContext is
+ // reseted, removing all the non-const cached values.
+ bool RunOnValueChangeOrTimeout(base::Closure callback);
+
private:
+ // Removes all the Observers and timeout callbacks scheduled by
+ // RunOnValueChangeOrTimeout(). This method is idempotent.
+ void RemoveObserversAndTimeout();
+
+ // BaseVariable::ObserverInterface override.
+ void ValueChanged(BaseVariable* var);
+
+ // Called from the main loop when the scheduled poll timeout has passed.
+ void OnPollTimeout();
+
+ // Removes the observers from the used Variables and cancels the poll timeout
+ // and executes the scheduled callback, if any.
+ void OnValueChangedOrPollTimeout();
+
// The remaining time for the current evaluation.
base::TimeDelta RemainingTime() const;
@@ -40,6 +69,13 @@
// The cached values of the called Variables.
ValueCacheMap value_cache_;
+ // A pointer to a copy of the closure passed to RunOnValueChangeOrTimeout().
+ scoped_ptr<base::Closure> value_changed_callback_;
+
+ // The EventId returned by the event loop identifying the timeout callback.
+ // Used to cancel the timeout callback.
+ EventId poll_timeout_event_ = kEventIdNull;
+
DISALLOW_COPY_AND_ASSIGN(EvaluationContext);
};