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 495162eefa12900b3a74bfbb269851473df4cce9
Author: Meng Zhu <[email protected]>
AuthorDate: Wed Jun 5 14:04:53 2019 -0700

    Refactored allocator with the new quota wrapper struct.
    
    This patch also introduces a constant `DEFAULT_QUOTA`.
    By default, a role has no guarantees and no limits.
    
    Review: https://reviews.apache.org/r/70801
---
 src/master/allocator/mesos/hierarchical.cpp | 49 +++++++++--------------------
 src/master/allocator/mesos/hierarchical.hpp | 19 ++---------
 src/master/constants.hpp                    |  4 +++
 3 files changed, 22 insertions(+), 50 deletions(-)

diff --git a/src/master/allocator/mesos/hierarchical.cpp 
b/src/master/allocator/mesos/hierarchical.cpp
index ad0bcca..a7c237e 100644
--- a/src/master/allocator/mesos/hierarchical.cpp
+++ b/src/master/allocator/mesos/hierarchical.cpp
@@ -1410,21 +1410,12 @@ void HierarchicalAllocatorProcess::setQuota(
   // the role is not set. Setting quota differs from updating it because
   // the former moves the role to a different allocation group with a
   // dedicated sorter, while the later just updates the actual quota.
-  CHECK(getGuarantees(role).empty() && getLimits(role).empty());
+  CHECK(getQuota(role) == DEFAULT_QUOTA);
 
   // In the legacy `SetQuota` call, quota guarantee also acts as quota limits.
   //
   // Note, quota has been validated to have no duplicate resource names.
-  roles[role].quotaLimits = [&]() {
-    google::protobuf::Map<string, Value::Scalar> limits;
-    foreach (const Resource& r, quota.info.guarantee()) {
-      limits[r.name()] = r.scalar();
-    }
-    return ResourceLimits(limits);
-  }();
-
-  roles[role].quotaGuarantees =
-    ResourceQuantities::fromScalarResources(quota.info.guarantee());
+  roles[role].quota = Quota2(quota.info);
 
   metrics.setQuota(role, quota);
 
@@ -1447,16 +1438,16 @@ void HierarchicalAllocatorProcess::removeQuota(
   CHECK(initialized);
 
   // Do not allow removing quota if it is not set.
-  CHECK(!getGuarantees(role).empty() || !getLimits(role).empty());
+  // Note: it is impossible to set to default quota using the old `setQuota`.
+  CHECK(getQuota(role) != DEFAULT_QUOTA);
 
   Role& r = roles.at(role);
 
   // TODO(alexr): Print all quota info for the role.
-  LOG(INFO) << "Removed quota " << r.quotaGuarantees
+  LOG(INFO) << "Removed quota " << r.quota.guarantees
             << " for role '" << role << "'";
 
-  r.quotaGuarantees = ResourceQuantities();
-  r.quotaLimits = ResourceLimits();
+  r.quota = DEFAULT_QUOTA;
   if (r.isEmpty()) {
     roles.erase(role);
   }
@@ -1657,7 +1648,7 @@ void HierarchicalAllocatorProcess::__allocate()
   foreachpair (const string& role, const Role& r, roles) {
     // TODO(mzhu): Track all role consumed quota. We may want to expose
     // these as metrics.
-    if (!r.quotaGuarantees.empty() || !r.quotaLimits.empty()) {
+    if (r.quota != DEFAULT_QUOTA) {
       logHeadroomInfo = true;
       // Note, `reservationScalarQuantities` in `struct role`
       // is hierarchical aware, thus it also includes subrole reservations.
@@ -1674,8 +1665,7 @@ void HierarchicalAllocatorProcess::__allocate()
     const string& topLevelRole = strings::contains(role, "/") ?
       role.substr(0, role.find('/')) : role;
 
-    if (getGuarantees(topLevelRole).empty() &&
-        getLimits(topLevelRole).empty()) {
+    if (getQuota(topLevelRole) == DEFAULT_QUOTA) {
       continue;
     }
 
@@ -1701,7 +1691,7 @@ void HierarchicalAllocatorProcess::__allocate()
   ResourceQuantities requiredHeadroom;
   foreachpair (const string& role, const Role& r, roles) {
     requiredHeadroom +=
-      r.quotaGuarantees -
+      r.quota.guarantees -
       rolesConsumedQuota.get(role).getOrElse(ResourceQuantities());
   }
 
@@ -1788,8 +1778,8 @@ void HierarchicalAllocatorProcess::__allocate()
     Slave& slave = slaves.at(slaveId);
 
     foreach (const string& role, roleSorter->sort()) {
-      const ResourceQuantities& quotaGuarantees = getGuarantees(role);
-      const ResourceLimits& quotaLimits = getLimits(role);
+      const ResourceQuantities& quotaGuarantees = getQuota(role).guarantees;
+      const ResourceLimits& quotaLimits = getQuota(role).limits;
 
       // We only allocate to roles with non-default guarantees
       // in the first stage.
@@ -2039,7 +2029,7 @@ void HierarchicalAllocatorProcess::__allocate()
         break; // Nothing left on this agent.
       }
 
-      const ResourceLimits& quotaLimits = getLimits(role);
+      const ResourceLimits& quotaLimits = getQuota(role).limits;
 
       // NOTE: Suppressed frameworks are not included in the sort.
       CHECK_CONTAINS(frameworkSorters, role);
@@ -2137,7 +2127,7 @@ void HierarchicalAllocatorProcess::__allocate()
         ResourceQuantities increasedQuotaConsumption =
           ResourceQuantities::fromScalarResources(additionalScalarAllocation);
 
-        if (!getGuarantees(role).empty() || !getLimits(role).empty()) {
+        if (getQuota(role) != DEFAULT_QUOTA) {
           rolesConsumedQuota[role] += increasedQuotaConsumption;
           for (const string& ancestor : roles::ancestors(role)) {
             rolesConsumedQuota[ancestor] += increasedQuotaConsumption;
@@ -2557,18 +2547,9 @@ bool 
HierarchicalAllocatorProcess::isFrameworkTrackedUnderRole(
 }
 
 
-const ResourceQuantities& HierarchicalAllocatorProcess::getGuarantees(
-    const string& role) const
-{
-  return roles.contains(role) ? roles.at(role).quotaGuarantees
-                              : defaultQuotaGuarantees;
-}
-
-
-const ResourceLimits& HierarchicalAllocatorProcess::getLimits(
-    const string& role) const
+const Quota2& HierarchicalAllocatorProcess::getQuota(const string& role) const
 {
-  return roles.contains(role) ? roles.at(role).quotaLimits : 
defaultQuotaLimits;
+  return roles.contains(role) ? roles.at(role).quota : DEFAULT_QUOTA;
 }
 
 
diff --git a/src/master/allocator/mesos/hierarchical.hpp 
b/src/master/allocator/mesos/hierarchical.hpp
index 1a3329d..0a6482a 100644
--- a/src/master/allocator/mesos/hierarchical.hpp
+++ b/src/master/allocator/mesos/hierarchical.hpp
@@ -119,15 +119,13 @@ struct Role
 
   // Configured guaranteed resource quantities and resource limits for
   // this role. By default, a role has no guarantee and no limit.
-  ResourceQuantities quotaGuarantees;
-  ResourceLimits quotaLimits;
+  Quota2 quota;
 
   bool isEmpty() const
   {
     return frameworks.empty() &&
            reservationScalarQuantities.empty() &&
-           quotaGuarantees.empty() &&
-           quotaLimits.empty();
+           quota == DEFAULT_QUOTA;
   }
 };
 
@@ -619,23 +617,12 @@ protected:
   // Factory function for framework sorters.
   const std::function<Sorter*()> frameworkSorterFactory;
 
-  // By default, roles have empty quota guarantees and limits.
-  //
-  // We keep this in memory so that roles that are absent in the `roles` map
-  // could also keep their quota state in memory.
-  //
-  // TODO(mzhu): remove this once we have proper role life cycle management
-  // such that every role would have an entry in the `roles` map.
-  const ResourceQuantities defaultQuotaGuarantees;
-  const ResourceLimits defaultQuotaLimits;
-
 private:
   bool isFrameworkTrackedUnderRole(
       const FrameworkID& frameworkId,
       const std::string& role) const;
 
-  const ResourceQuantities& getGuarantees(const std::string& role) const;
-  const ResourceLimits& getLimits(const std::string& role) const;
+  const Quota2& getQuota(const std::string& role) const;
 
   void trackFrameworkUnderRole(
       const FrameworkID& frameworkId,
diff --git a/src/master/constants.hpp b/src/master/constants.hpp
index 8f729d1..8502240 100644
--- a/src/master/constants.hpp
+++ b/src/master/constants.hpp
@@ -20,6 +20,7 @@
 #include <stdint.h>
 
 #include <mesos/mesos.hpp>
+#include <mesos/quota/quota.hpp>
 
 #include <stout/bytes.hpp>
 #include <stout/duration.hpp>
@@ -172,6 +173,9 @@ const Version MINIMUM_AGENT_VERSION = Version(1, 0, 0);
 
 std::vector<MasterInfo::Capability> MASTER_CAPABILITIES();
 
+// A role's default quota: no guarantees and no limits.
+const Quota2 DEFAULT_QUOTA;
+
 } // namespace master {
 } // namespace internal {
 } // namespace mesos {

Reply via email to