This is an automated email from the ASF dual-hosted git repository.

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 6d77d7784c41cc13eb856e337a2f7a77cf3d2554
Author: Andrei Sekretenko <asekrete...@mesosphere.io>
AuthorDate: Fri Oct 4 18:14:56 2019 -0400

    Replaced removal+adding of quota metrics with updating them.
    
    This patch factor out the common code for updating quota guarantee
    and quota limit metrics, and replaces pairs of
    `process::metrics::remove()`/`process::metrics::add()` called for the
    same metric with calling `PushGauge::operator = ()`. This is
    a perequisite for adding PushGauge-based quota consumption metrics.
    
    Review: https://reviews.apache.org/r/71489/
---
 src/master/allocator/mesos/metrics.cpp | 107 ++++++++++++++++-----------------
 src/master/allocator/mesos/metrics.hpp |  25 ++++++++
 2 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/src/master/allocator/mesos/metrics.cpp 
b/src/master/allocator/mesos/metrics.cpp
index ba95dc4..6a8d369 100644
--- a/src/master/allocator/mesos/metrics.cpp
+++ b/src/master/allocator/mesos/metrics.cpp
@@ -43,6 +43,53 @@ namespace master {
 namespace allocator {
 namespace internal {
 
+
+template<class Quantities>
+void QuotaMetrics::update(const string& role, const Quantities& quantities)
+{
+  hashmap<string, PushGauge>& gauges = metrics[role];
+
+  hashset<string> namesToRemove = gauges.keys();
+
+  for (const auto& quantity : quantities) {
+    const string& name = quantity.first;
+    const double value = quantity.second.value();
+
+    namesToRemove.erase(name);
+
+    if (gauges.contains(name)) {
+      gauges.at(name) = value;
+      continue;
+    }
+
+    PushGauge newGauge(
+        "allocator/mesos/quota/roles/" + role + "/resources/" + name + suffix);
+
+    newGauge = value;
+    process::metrics::add(newGauge);
+    gauges.put(name, newGauge);
+  }
+
+  for (const string& name : namesToRemove) {
+    process::metrics::remove(gauges.at(name));
+    gauges.erase(name);
+  }
+
+  if (gauges.empty()) {
+    metrics.erase(role);
+  }
+}
+
+
+QuotaMetrics::~QuotaMetrics() {
+  foreachkey(const string& role, metrics) {
+    foreachvalue(const PushGauge& gauge, metrics.at(role)) {
+      process::metrics::remove(gauge);
+    }
+  }
+}
+
+
 Metrics::Metrics(const HierarchicalAllocatorProcess& _allocator)
   : allocator(_allocator.self()),
     event_queue_dispatches(
@@ -116,18 +163,6 @@ Metrics::~Metrics()
     }
   }
 
-  foreachkey (const string& role, quota_guarantee) {
-    foreachvalue (const PushGauge& gauge, quota_guarantee.at(role)) {
-      process::metrics::remove(gauge);
-    }
-  }
-
-  foreachkey (const string& role, quota_limit) {
-    foreachvalue (const PushGauge& gauge, quota_limit.at(role)) {
-      process::metrics::remove(gauge);
-    }
-  }
-
   foreachvalue (const PullGauge& gauge, offer_filters_active) {
     process::metrics::remove(gauge);
   }
@@ -136,63 +171,27 @@ Metrics::~Metrics()
 
 void Metrics::updateQuota(const string& role, const Quota& quota)
 {
+  quotaGuarantees.update(role, quota.guarantees);
+  quotaLimits.update(role, quota.limits);
+
   // First remove the existing metrics.
   foreachvalue (const PullGauge& gauge, quota_allocated[role]) {
     process::metrics::remove(gauge);
   }
   quota_allocated.erase(role);
 
-  foreachvalue (const PushGauge& gauge, quota_guarantee[role]) {
-    process::metrics::remove(gauge);
-  }
-  quota_guarantee.erase(role);
-
-  foreachvalue (const PushGauge& gauge, quota_limit[role]) {
-    process::metrics::remove(gauge);
-  }
-  quota_limit.erase(role);
-
   // This is the original quota "remove" case where the
   // role's quota is set to the default. We used to not
   // show the quota allocated_or_offered metric in this
   // case, so we keep this behavior for now.
   //
-  // TODO(mzhu): always expose the allocated gauge even
-  // if a role only has default quota.
+  // TODO(asekretenko): move offered_or_allocated to PushGauge-based
+  // QuotaMetrics. This also solves the problem of exposing consumption of
+  // roles with a default quota.
   if (quota == DEFAULT_QUOTA) {
     return;
   }
 
-  // Now add the new metrics.
-
-  foreach (auto& quantity, quota.guarantees) {
-    PushGauge guarantee(
-        "allocator/mesos/quota"
-        "/roles/" + role +
-        "/resources/" + quantity.first +
-        "/guarantee");
-
-    guarantee = quantity.second.value();
-
-    process::metrics::add(guarantee);
-
-    quota_guarantee[role].put(quantity.first, guarantee);
-  }
-
-  foreach (auto& quantity, quota.limits) {
-    PushGauge limit(
-        "allocator/mesos/quota"
-        "/roles/" + role +
-        "/resources/" + quantity.first +
-        "/limit");
-
-    limit = quantity.second.value();
-
-    process::metrics::add(limit);
-
-    quota_limit[role].put(quantity.first, limit);
-  }
-
   hashset<string> names;
 
   foreach (auto& quantity, quota.guarantees) {
diff --git a/src/master/allocator/mesos/metrics.hpp 
b/src/master/allocator/mesos/metrics.hpp
index adb9515..d2cb41b 100644
--- a/src/master/allocator/mesos/metrics.hpp
+++ b/src/master/allocator/mesos/metrics.hpp
@@ -23,6 +23,7 @@
 #include <mesos/quota/quota.hpp>
 
 #include <process/metrics/counter.hpp>
+#include <process/metrics/metrics.hpp>
 #include <process/metrics/pull_gauge.hpp>
 #include <process/metrics/push_gauge.hpp>
 #include <process/metrics/timer.hpp>
@@ -40,6 +41,24 @@ namespace internal {
 // Forward declarations.
 class HierarchicalAllocatorProcess;
 
+
+class QuotaMetrics
+{
+public:
+  explicit QuotaMetrics(const std::string& suffix_) : suffix(suffix_){};
+  ~QuotaMetrics();
+
+  template <class Quantities>
+  void update(const std::string& role, const Quantities& quantities);
+
+private:
+  const std::string suffix;
+
+  hashmap<std::string, hashmap<std::string, process::metrics::PushGauge>>
+    metrics;
+};
+
+
 // Collection of metrics for the allocator; these begin
 // with the following prefix: `allocator/mesos/`.
 struct Metrics
@@ -92,6 +111,12 @@ struct Metrics
 
   // PullGauges for the per-role count of active offer filters.
   hashmap<std::string, process::metrics::PullGauge> offer_filters_active;
+
+private:
+  // NOTE: Quota metrics should have a suffix in singilar.
+  // (Example of a name: 
allocator/mesos/quota/roles/roleA/resources/cpu/limit.)
+  QuotaMetrics quotaGuarantees {"/guarantee"};
+  QuotaMetrics quotaLimits {"/limit"};
 };
 
 

Reply via email to