You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mz...@apache.org on 2019/07/23 22:04:43 UTC

[mesos] 02/06: Refactored master's role ResourceBreakdown to compute results lazily.

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 76a70957682125abf71407202e56d18fde12d1cf
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Wed Jul 17 16:32:33 2019 -0700

    Refactored master's role ResourceBreakdown to compute results lazily.
    
    This breaks the computation of offered, allocated, reserved
    and consumedQuota into separate getter functions which are
    lazily calculated upon invoked. The struct is renamed to
    `RoleResourceBreakdown`.
    
    Review: https://reviews.apache.org/r/71110
---
 src/master/master.cpp           | 107 +++++++++++++++-------------------------
 src/master/master.hpp           |  24 +++++----
 src/master/readonly_handler.cpp |  22 ++++-----
 3 files changed, 64 insertions(+), 89 deletions(-)

diff --git a/src/master/master.cpp b/src/master/master.cpp
index fbde112..31c7c97 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -3611,90 +3611,63 @@ bool Master::isWhitelistedRole(const string& name) const
 }
 
 
-hashmap<string, Master::ResourceBreakdown>
-  Master::getRoleTreeResourceQuantities() const
-{
-  auto allocatedToRoleSubtree = [](const string& role) {
-    return [&](const Resource& r) {
-      CHECK(r.has_allocation_info());
-      return r.allocation_info().role() == role ||
-        roles::isStrictSubroleOf(r.allocation_info().role(), role);
-    };
-  };
-
-  auto reservedToRoleSubtree = [](const string& role) {
-    return [&](const Resource& r) {
-      return Resources::isReserved(r) &&
-        (Resources::reservationRole(r) == role ||
-         roles::isStrictSubroleOf(Resources::reservationRole(r), role));
-    };
-  };
-
-  auto offered = [&](const string& role) {
-    ResourceQuantities total;
+ResourceQuantities Master::RoleResourceBreakdown::offered() const
+{
+  ResourceQuantities result;
 
-    foreachvalue (Framework* framework, frameworks.registered) {
-      total += ResourceQuantities::fromResources(
-          framework->totalOfferedResources
-            .filter(allocatedToRoleSubtree(role)));
-    }
+  foreachvalue (Framework* framework, master->frameworks.registered) {
+    result += ResourceQuantities::fromResources(
+        framework->totalOfferedResources.allocatedToRoleSubtree(role));
+  }
 
-    return total;
-  };
+  return result;
+}
 
-  auto allocated = [&](const string& role) {
-    ResourceQuantities total;
 
-    foreachvalue (Framework* framework, frameworks.registered) {
-      total += ResourceQuantities::fromResources(
-          framework->totalUsedResources.filter(allocatedToRoleSubtree(role)));
-    }
+ResourceQuantities Master::RoleResourceBreakdown::allocated() const
+{
+  ResourceQuantities result;
 
-    return total;
-  };
+  foreachvalue (Framework* framework, master->frameworks.registered) {
+    result += ResourceQuantities::fromResources(
+        framework->totalUsedResources.allocatedToRoleSubtree(role));
+  }
 
-  auto reserved = [&](const string& role) {
-    ResourceQuantities total;
+  return result;
+}
 
-    foreachvalue (Slave* slave, slaves.registered) {
-      total += ResourceQuantities::fromResources(
-          slave->totalResources.filter(reservedToRoleSubtree(role)));
-    }
 
-    return total;
-  };
+ResourceQuantities Master::RoleResourceBreakdown::reserved() const
+{
+  ResourceQuantities result;
 
-  // Consumed quota = allocation + unallocated reservation.
-  auto consumedQuota = [&](const string& role) {
-    ResourceQuantities unallocatedReservation;
+  foreachvalue (Slave* slave, master->slaves.registered) {
+    result += ResourceQuantities::fromResources(
+        slave->totalResources.reservedToRoleSubtree(role));
+  }
 
-    foreachvalue (Slave* slave, slaves.registered) {
-      ResourceQuantities totalReservation =
-        ResourceQuantities::fromResources(
-           slave->totalResources.filter(reservedToRoleSubtree(role)));
+  return result;
+}
 
-       ResourceQuantities usedReservation;
-       foreachvalue (const Resources& r, slave->usedResources) {
-         usedReservation += ResourceQuantities::fromResources(
-             r.filter(reservedToRoleSubtree(role)));
-       }
 
-       unallocatedReservation += totalReservation - usedReservation;
-     }
+ResourceQuantities Master::RoleResourceBreakdown::consumedQuota() const
+{
+  ResourceQuantities unallocatedReservation;
 
-    return allocated(role) + unallocatedReservation;
-  };
+  foreachvalue (Slave* slave, master->slaves.registered) {
+    ResourceQuantities totalReservation = ResourceQuantities::fromResources(
+        slave->totalResources.reservedToRoleSubtree(role));
 
-  hashmap<string, ResourceBreakdown> result;
+    ResourceQuantities usedReservation;
+    foreachvalue (const Resources& r, slave->usedResources) {
+      usedReservation += ResourceQuantities::fromResources(
+          r.reservedToRoleSubtree(role));
+    }
 
-  foreach (const string& role, knownRoles()) {
-    result[role].offered = offered(role);
-    result[role].allocated = allocated(role);
-    result[role].reserved = reserved(role);
-    result[role].consumedQuota = consumedQuota(role);
+    unallocatedReservation += totalReservation - usedReservation;
   }
 
-  return result;
+  return allocated() + unallocatedReservation;
 }
 
 
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 5c229c5..cacdcfd 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1188,19 +1188,25 @@ private:
    */
   bool isWhitelistedRole(const std::string& name) const;
 
-  struct ResourceBreakdown
-  {
-    ResourceQuantities offered;
-    ResourceQuantities allocated;
-    ResourceQuantities reserved;
-    ResourceQuantities consumedQuota;
-  };
-
   // TODO(bmahler): Store a role tree rather than the existing
   // `roles` map which does not track the tree correctly (it does
   // not insert ancestor entries, nor does it track roles if there
   // are reservations but no frameworks related to them).
-  hashmap<std::string, ResourceBreakdown> getRoleTreeResourceQuantities() const;
+  struct RoleResourceBreakdown
+  {
+  public:
+    RoleResourceBreakdown(const Master* const master_, const std::string& role_)
+      : master(master_), role(role_) {}
+
+    ResourceQuantities offered() const;
+    ResourceQuantities allocated() const;
+    ResourceQuantities reserved() const;
+    ResourceQuantities consumedQuota() const;
+
+  private:
+    const Master* const master;
+    const std::string role;
+  };
 
   // Performs validations of the FrameworkInfo and suppressed roles set
   // which do not depend on the current state of this framework.
diff --git a/src/master/readonly_handler.cpp b/src/master/readonly_handler.cpp
index 60dac9a..a893115 100644
--- a/src/master/readonly_handler.cpp
+++ b/src/master/readonly_handler.cpp
@@ -719,8 +719,6 @@ process::http::Response Master::ReadOnlyHandler::roles(
   const Master* master = this->master;
 
   const vector<string> knownRoles = master->knownRoles();
-  const hashmap<string, ResourceBreakdown> resourceBreakdowns =
-    master->getRoleTreeResourceQuantities();
 
   auto roles = [&](JSON::ObjectWriter* writer) {
     writer->field(
@@ -739,10 +737,7 @@ process::http::Response Master::ReadOnlyHandler::roles(
 
               Option<Role*> role = master->roles.get(name);
 
-              CHECK_CONTAINS(resourceBreakdowns, name);
-
-              const ResourceBreakdown& resourceBreakdown =
-                resourceBreakdowns.at(name);
+              RoleResourceBreakdown resourceBreakdown(master, name);
 
               // Prior to Mesos 1.9, this field is filled based on
               // `QuotaInfo` which is now deprecated. For backward
@@ -762,17 +757,18 @@ process::http::Response Master::ReadOnlyHandler::roles(
 
                 writer->field("guarantee", quota.guarantees);
                 writer->field("limit", quota.limits);
-                writer->field("consumed", resourceBreakdown.consumedQuota);
+                writer->field("consumed", resourceBreakdown.consumedQuota());
               });
 
+              ResourceQuantities allocated = resourceBreakdown.allocated();
+              ResourceQuantities offered = resourceBreakdown.offered();
+
               // Deprecated by allocated, offered, reserved.
-              writer->field(
-                  "resources",
-                  resourceBreakdown.allocated + resourceBreakdown.offered);
+              writer->field("resources", allocated + offered);
 
-              writer->field("allocated", resourceBreakdown.allocated);
-              writer->field("offered", resourceBreakdown.offered);
-              writer->field("reserved", resourceBreakdown.reserved);
+              writer->field("allocated", allocated);
+              writer->field("offered", offered);
+              writer->field("reserved", resourceBreakdown.reserved());
 
               if (role.isNone()) {
                 writer->field("frameworks", [](JSON::ArrayWriter*) {});