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

[mesos] branch master updated (f9fa16b -> 6b7dd46)

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

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


    from f9fa16b  Added MESOS-9870 to the 1.5.4 CHANGELOG.
     new f0285ec  Added ability to revive a subset of roles in the scheduler driver.
     new f674ce7  Added a scheduler driver test for 'reviveOffers(roles)'.
     new 57c2b70  Added ability to suppress a subset of roles in the scheduler driver.
     new 6b7dd46  Added a scheduler driver test for 'suppressOffers(roles)'.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 include/mesos/scheduler.hpp          |  19 ++++
 src/sched/sched.cpp                  |  90 ++++++++++++++++---
 src/tests/scheduler_driver_tests.cpp | 169 +++++++++++++++++++++++++++++++++++
 3 files changed, 265 insertions(+), 13 deletions(-)


[mesos] 02/04: Added a scheduler driver test for 'reviveOffers(roles)'.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f674ce74ba1629627f4119d6f50528ad1d600812
Author: Andrei Sekretenko <as...@mesosphere.io>
AuthorDate: Wed Jul 3 18:47:26 2019 -0400

    Added a scheduler driver test for 'reviveOffers(roles)'.
    
    Review: https://reviews.apache.org/r/70942/
---
 src/tests/scheduler_driver_tests.cpp | 97 ++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/src/tests/scheduler_driver_tests.cpp b/src/tests/scheduler_driver_tests.cpp
index 80f3335..c0124bf 100644
--- a/src/tests/scheduler_driver_tests.cpp
+++ b/src/tests/scheduler_driver_tests.cpp
@@ -62,6 +62,8 @@ using process::PID;
 
 using process::http::OK;
 
+using std::set;
+using std::string;
 using std::vector;
 
 using testing::_;
@@ -554,6 +556,101 @@ TEST_F(MesosSchedulerDriverTest, RegisterWithSuppressedRole)
   driver.join();
 }
 
+
+// This test ensures that reviveOffers() can unsuppress
+// one role of a multi-role framework.
+//
+// We subscribe a framework with two roles, decline offers
+// for both, call reviveOffers() for the second role and
+// check that only the first one is filtered after that.
+TEST_F(MesosSchedulerDriverTest, ReviveSingleRole)
+{
+  mesos::internal::master::Flags masterFlags = CreateMasterFlags();
+  masterFlags.allocation_interval = Milliseconds(5);
+
+  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
+  ASSERT_SOME(master);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get());
+  ASSERT_SOME(slave);
+
+  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+
+  frameworkInfo.clear_roles();
+  frameworkInfo.add_roles("role1");
+  frameworkInfo.add_roles("role2");
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  Future<FrameworkID> frameworkId;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureArg<1>(&frameworkId));
+
+  Future<vector<Offer>> offers1;
+  Future<vector<Offer>> offers2;
+
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers1))
+    .WillOnce(FutureArg<1>(&offers2));
+
+  driver.start();
+
+  // Decline offers for both roles and set a long filter.
+  Filters filter1day;
+  filter1day.set_refuse_seconds(Days(1).secs());
+
+  set<string> declinedOfferRoles;
+
+  AWAIT_READY(offers1);
+  ASSERT_EQ(1u, offers1->size());
+  driver.declineOffer(offers1.get()[0].id(), filter1day);
+  declinedOfferRoles.emplace(offers1.get()[0].allocation_info().role());
+
+  AWAIT_READY(offers2);
+  ASSERT_EQ(1u, offers2->size());
+  driver.declineOffer(offers2.get()[0].id(), filter1day);
+  declinedOfferRoles.emplace(offers2.get()[0].allocation_info().role());
+
+  // Sanity check: we should have responed to offers for both roles.
+  ASSERT_EQ(set<string>({"role1", "role2"}), declinedOfferRoles);
+
+  // In addition to setting a filter, suppress role2 (to check that
+  // reviveOffers() not only removes filters, but also unsuppresses roles).
+  *frameworkInfo.mutable_id() = frameworkId.get();
+  driver.updateFramework(frameworkInfo, {"role2"});
+
+  // Wait for updateFramework() to be dispatched to the allocator.
+  // Otherwise, REVIVE might be processed by the allocator before the update.
+  Clock::pause();
+  Clock::settle();
+
+  // After reviving role2 we expect offers EXACTLY once, for role2.
+  Future<vector<Offer>> offersOnRevival;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offersOnRevival));
+
+  driver.reviveOffers({"role2"});
+
+  AWAIT_READY(offersOnRevival);
+  ASSERT_EQ(1u, offersOnRevival->size());
+  ASSERT_EQ("role2", offersOnRevival.get()[0].allocation_info().role());
+
+  // Decline the offer for role2 and set a filter.
+  driver.declineOffer(offersOnRevival.get()[0].id(), filter1day);
+  Clock::settle();
+
+  // Trigger allocation to ensure that role1 still has a filter.
+  Clock::advance(masterFlags.allocation_interval);
+  Clock::settle();
+
+  driver.stop();
+  driver.join();
+}
+
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {


[mesos] 03/04: Added ability to suppress a subset of roles in the scheduler driver.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 57c2b7098ee523f3f0f647c6b334cce37266fe2a
Author: Andrei Sekretenko <as...@mesosphere.io>
AuthorDate: Wed Jul 3 18:47:53 2019 -0400

    Added ability to suppress a subset of roles in the scheduler driver.
    
    This patch adds to the scheduler driver a 'suppressOffers(roles)'
    method, which sends the SUPPRESS call for these roles and adds them to
    the suppressed roles set.
    
    Review: https://reviews.apache.org/r/70983/
---
 include/mesos/scheduler.hpp |  9 +++++++++
 src/sched/sched.cpp         | 44 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/include/mesos/scheduler.hpp b/include/mesos/scheduler.hpp
index cc3a278..61cc846 100644
--- a/include/mesos/scheduler.hpp
+++ b/include/mesos/scheduler.hpp
@@ -312,6 +312,13 @@ public:
   // re-registration.
   virtual Status suppressOffers() = 0;
 
+  // Adds the roles to the suppressed set. If the framework is not connected
+  // to the master, an up-to-date set of suppressed roles will be sent to
+  // the master during re-registration.
+  //
+  // NOTE: If 'roles' is empty, this method does nothing.
+  virtual Status suppressOffers(const std::vector<std::string>& roles) = 0;
+
   // Acknowledges the status update. This should only be called
   // once the status update is processed durably by the scheduler.
   // Not that explicit acknowledgements must be requested via the
@@ -502,6 +509,8 @@ public:
 
   Status suppressOffers() override;
 
+  Status suppressOffers(const std::vector<std::string>& roles) override;
+
   Status acknowledgeStatusUpdate(
       const TaskStatus& status) override;
 
diff --git a/src/sched/sched.cpp b/src/sched/sched.cpp
index 47b87ad..768ce7d 100644
--- a/src/sched/sched.cpp
+++ b/src/sched/sched.cpp
@@ -1475,10 +1475,16 @@ protected:
     send(master->pid(), call);
   }
 
-  void suppressOffers()
+  void suppressOffers(const vector<string>& roles)
   {
-    suppressedRoles =
-      std::set<string>(framework.roles().begin(), framework.roles().end());
+    if (roles.empty()) {
+      suppressedRoles =
+        std::set<string>(framework.roles().begin(), framework.roles().end());
+    } else {
+      for (const string& role : roles) {
+        suppressedRoles.emplace(role);
+      }
+    }
 
     if (!connected) {
       VLOG(1) << "Ignoring SUPPRESS as master is disconnected;"
@@ -1489,14 +1495,20 @@ protected:
       return;
     }
 
-    VLOG(2) << "Sending SUPPRESS for all roles";
-
     Call call;
 
     CHECK(framework.has_id());
     call.mutable_framework_id()->CopyFrom(framework.id());
     call.set_type(Call::SUPPRESS);
 
+    if (roles.empty()) {
+      VLOG(2) << "Sending SUPPRESS for all roles";
+    } else {
+      VLOG(2) << "Sending SUPPRESS for roles: " << stringify(roles);
+      *call.mutable_suppress()->mutable_roles() =
+        RepeatedPtrField<string>(roles.begin(), roles.end());
+    }
+
     CHECK_SOME(master);
     send(master->pid(), call);
   }
@@ -2375,7 +2387,27 @@ Status MesosSchedulerDriver::suppressOffers()
 
     CHECK(process != nullptr);
 
-    dispatch(process, &SchedulerProcess::suppressOffers);
+    dispatch(process, &SchedulerProcess::suppressOffers, vector<string>());
+
+    return status;
+  }
+}
+
+
+Status MesosSchedulerDriver::suppressOffers(const vector<string>& roles)
+{
+  if (roles.empty()) {
+    return status;
+  }
+
+  synchronized (mutex) {
+    if (status != DRIVER_RUNNING) {
+      return status;
+    }
+
+    CHECK(process != nullptr);
+
+    dispatch(process, &SchedulerProcess::suppressOffers, roles);
 
     return status;
   }


[mesos] 01/04: Added ability to revive a subset of roles in the scheduler driver.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f0285ecbfd38a60e17937834aec58d0a9235d1d7
Author: Andrei Sekretenko <as...@mesosphere.io>
AuthorDate: Wed Jul 3 18:46:30 2019 -0400

    Added ability to revive a subset of roles in the scheduler driver.
    
    This patch adds to the scheduler driver a 'reviveOffers(roles)' method,
    which sends the REVIVE call for these roles and removes them from the
    suppressed roles set.
    
    Review: https://reviews.apache.org/r/70941/
---
 include/mesos/scheduler.hpp | 10 ++++++++++
 src/sched/sched.cpp         | 46 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/include/mesos/scheduler.hpp b/include/mesos/scheduler.hpp
index 0a09d55..cc3a278 100644
--- a/include/mesos/scheduler.hpp
+++ b/include/mesos/scheduler.hpp
@@ -293,6 +293,14 @@ public:
   // during re-registration.
   virtual Status reviveOffers() = 0;
 
+  // Removes filters for the specified roles and removes  these roles from
+  // the suppressed set.  If the framework is not connected to the master,
+  // an up-to-date set of suppressed roles will be sent to the master
+  // during re-registration.
+  //
+  // NOTE: If 'roles' is empty, this method does nothing.
+  virtual Status reviveOffers(const std::vector<std::string>& roles) = 0;
+
   // Informs Mesos master to stop sending offers to the framework (i.e.
   // to suppress all roles of the framework). To resume getting offers,
   // the scheduler can call reviveOffers() or set the suppressed roles
@@ -490,6 +498,8 @@ public:
 
   Status reviveOffers() override;
 
+  Status reviveOffers(const std::vector<std::string>& roles) override;
+
   Status suppressOffers() override;
 
   Status acknowledgeStatusUpdate(
diff --git a/src/sched/sched.cpp b/src/sched/sched.cpp
index 6b02ac0..47b87ad 100644
--- a/src/sched/sched.cpp
+++ b/src/sched/sched.cpp
@@ -116,6 +116,7 @@ using process::Process;
 using process::UPID;
 
 using std::map;
+using std::make_move_iterator;
 using std::mutex;
 using std::shared_ptr;
 using std::set;
@@ -1438,27 +1439,38 @@ protected:
     send(master->pid(), call);
   }
 
-  void reviveOffers()
+  void reviveOffers(const vector<string>& roles)
   {
-    suppressedRoles.clear();
+    if (roles.empty()) {
+      suppressedRoles.clear();
+    } else {
+      for (const string& role : roles) {
+        suppressedRoles.erase(role);
+      }
+    }
 
     if (!connected) {
       VLOG(1) << "Ignoring REVIVE as master is disconnected;"
-              << " the set of suppressed roles in the driver has been cleared"
+              << " the set of suppressed roles in the driver has been updated"
               << " and will be sent to the master during re-registration";
-
       sendUpdateFrameworkOnConnect = true;
       return;
     }
 
-    VLOG(2) << "Sending REVIVE for all roles";
-
     Call call;
 
     CHECK(framework.has_id());
     call.mutable_framework_id()->CopyFrom(framework.id());
     call.set_type(Call::REVIVE);
 
+    if (roles.empty()) {
+      VLOG(2) << "Sending REVIVE for all roles";
+    } else {
+      VLOG(2) << "Sending REVIVE for roles: " << stringify(roles);
+      *call.mutable_revive()->mutable_roles() =
+        RepeatedPtrField<string>(roles.begin(), roles.end());
+    }
+
     CHECK_SOME(master);
     send(master->pid(), call);
   }
@@ -2327,7 +2339,27 @@ Status MesosSchedulerDriver::reviveOffers()
 
     CHECK(process != nullptr);
 
-    dispatch(process, &SchedulerProcess::reviveOffers);
+    dispatch(process, &SchedulerProcess::reviveOffers, vector<string>());
+
+    return status;
+  }
+}
+
+
+Status MesosSchedulerDriver::reviveOffers(const vector<string>& roles)
+{
+  if (roles.empty()) {
+    return status;
+  }
+
+  synchronized (mutex) {
+    if (status != DRIVER_RUNNING) {
+      return status;
+    }
+
+    CHECK(process != nullptr);
+
+    dispatch(process, &SchedulerProcess::reviveOffers, roles);
 
     return status;
   }


[mesos] 04/04: Added a scheduler driver test for 'suppressOffers(roles)'.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6b7dd466cac37d891562fb0d1c92bfe0615e02cc
Author: Andrei Sekretenko <as...@mesosphere.io>
AuthorDate: Wed Jul 3 18:48:25 2019 -0400

    Added a scheduler driver test for 'suppressOffers(roles)'.
    
    Review: https://reviews.apache.org/r/70984/
---
 src/tests/scheduler_driver_tests.cpp | 72 ++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/src/tests/scheduler_driver_tests.cpp b/src/tests/scheduler_driver_tests.cpp
index c0124bf..63d7a3b 100644
--- a/src/tests/scheduler_driver_tests.cpp
+++ b/src/tests/scheduler_driver_tests.cpp
@@ -557,6 +557,78 @@ TEST_F(MesosSchedulerDriverTest, RegisterWithSuppressedRole)
 }
 
 
+// This test ensures that suppressOffers() can suppress
+// one role of a multi-role framework.
+//
+// We subscribe a framework with two roles, suppress the first one, decline
+// the offer for the second one, and expect to receive no offers after that.
+TEST_F(MesosSchedulerDriverTest, SuppressSingleRole)
+{
+  mesos::internal::master::Flags masterFlags = CreateMasterFlags();
+  masterFlags.allocation_interval = Milliseconds(5);
+
+  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
+  ASSERT_SOME(master);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+
+  frameworkInfo.clear_roles();
+  frameworkInfo.add_roles("role1");
+  frameworkInfo.add_roles("role2");
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  Future<Nothing> registered;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureSatisfy(&registered));
+
+  Future<vector<Offer>> offers;
+
+  // We should get offers EXACTLY once - for role2, which we don't suppress.
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers));
+
+  driver.start();
+
+  AWAIT_READY(registered);
+
+  driver.suppressOffers({"role1"});
+
+  // Ensure the suppression is processed by the master before
+  // adding the agent, otherwise the offer could go to role1.
+  Clock::pause();
+  Clock::settle();
+  Clock::resume();
+
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get());
+  ASSERT_SOME(slave);
+
+  // Decline an offer for role2 and set a long filter.
+  Filters filter1day;
+  filter1day.set_refuse_seconds(Days(1).secs());
+
+  AWAIT_READY(offers);
+  ASSERT_EQ(1u, offers->size());
+  ASSERT_EQ("role2", offers.get()[0].allocation_info().role());
+
+  driver.declineOffer(offers.get()[0].id(), filter1day);
+
+  // Trigger allocation and expect no offers
+  // (we are checking that role1 is indeed suppressed).
+  Clock::pause();
+  Clock::settle();
+
+  Clock::advance(masterFlags.allocation_interval);
+  Clock::settle();
+
+  driver.stop();
+  driver.join();
+}
+
+
 // This test ensures that reviveOffers() can unsuppress
 // one role of a multi-role framework.
 //