Added V1 Support for QuiesceOffers. Review: https://reviews.apache.org/r/38124
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/63f1c2ec Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/63f1c2ec Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/63f1c2ec Branch: refs/heads/master Commit: 63f1c2ec861a8fd527c89a37ce0f87b4735aa39f Parents: dd3fbe8 Author: Guangya Liu <[email protected]> Authored: Fri Sep 18 16:16:19 2015 -0700 Committer: Vinod Kone <[email protected]> Committed: Fri Sep 18 16:16:19 2015 -0700 ---------------------------------------------------------------------- include/mesos/v1/scheduler/scheduler.proto | 1 + src/master/http.cpp | 4 + src/master/validation.cpp | 3 + src/tests/scheduler_tests.cpp | 106 ++++++++++++++++++++++++ 4 files changed, 114 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/63f1c2ec/include/mesos/v1/scheduler/scheduler.proto ---------------------------------------------------------------------- diff --git a/include/mesos/v1/scheduler/scheduler.proto b/include/mesos/v1/scheduler/scheduler.proto index 0118b46..bc19b8d 100644 --- a/include/mesos/v1/scheduler/scheduler.proto +++ b/include/mesos/v1/scheduler/scheduler.proto @@ -174,6 +174,7 @@ message Call { RECONCILE = 9; // See 'Reconcile' below. MESSAGE = 10; // See 'Message' below. REQUEST = 11; // See 'Request' below. + QUIESCE = 12; // Inform master to stop sending offers to the framework. // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for // already subscribed frameworks as a way of stopping offers from http://git-wip-us.apache.org/repos/asf/mesos/blob/63f1c2ec/src/master/http.cpp ---------------------------------------------------------------------- diff --git a/src/master/http.cpp b/src/master/http.cpp index 8bb5935..7cca8b1 100644 --- a/src/master/http.cpp +++ b/src/master/http.cpp @@ -482,6 +482,10 @@ Future<Response> Master::Http::scheduler(const Request& request) const master->revive(framework); return Accepted(); + case scheduler::Call::QUIESCE: + master->quiesce(framework); + return Accepted(); + case scheduler::Call::KILL: master->kill(framework, call.kill()); return Accepted(); http://git-wip-us.apache.org/repos/asf/mesos/blob/63f1c2ec/src/master/validation.cpp ---------------------------------------------------------------------- diff --git a/src/master/validation.cpp b/src/master/validation.cpp index f97eba6..0f3fc1a 100644 --- a/src/master/validation.cpp +++ b/src/master/validation.cpp @@ -97,6 +97,9 @@ Option<Error> validate(const mesos::scheduler::Call& call) case mesos::scheduler::Call::REVIVE: return None(); + case mesos::scheduler::Call::QUIESCE: + return None(); + case mesos::scheduler::Call::KILL: if (!call.has_kill()) { return Error("Expecting 'kill' to be present"); http://git-wip-us.apache.org/repos/asf/mesos/blob/63f1c2ec/src/tests/scheduler_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/scheduler_tests.cpp b/src/tests/scheduler_tests.cpp index 77c2635..0f892f9 100644 --- a/src/tests/scheduler_tests.cpp +++ b/src/tests/scheduler_tests.cpp @@ -941,6 +941,112 @@ TEST_P(SchedulerTest, Revive) } +TEST_P(SchedulerTest, Quiesce) +{ + master::Flags flags = CreateMasterFlags(); + flags.authenticate_frameworks = false; + + Try<PID<Master>> master = StartMaster(flags); + ASSERT_SOME(master); + + Try<PID<Slave>> slave = StartSlave(); + ASSERT_SOME(slave); + + Callbacks callbacks; + + Future<Nothing> connected; + EXPECT_CALL(callbacks, connected()) + .WillOnce(FutureSatisfy(&connected)); + + Mesos mesos( + master.get(), + GetParam(), + lambda::bind(&Callbacks::connected, lambda::ref(callbacks)), + lambda::bind(&Callbacks::disconnected, lambda::ref(callbacks)), + lambda::bind(&Callbacks::received, lambda::ref(callbacks), lambda::_1)); + + AWAIT_READY(connected); + + Queue<Event> events; + + EXPECT_CALL(callbacks, received(_)) + .WillRepeatedly(Enqueue(&events)); + + { + Call call; + call.set_type(Call::SUBSCRIBE); + + Call::Subscribe* subscribe = call.mutable_subscribe(); + subscribe->mutable_framework_info()->CopyFrom(DEFAULT_V1_FRAMEWORK_INFO); + + mesos.send(call); + } + + Future<Event> event = events.get(); + AWAIT_READY(event); + EXPECT_EQ(Event::SUBSCRIBED, event.get().type()); + + v1::FrameworkID id(event.get().subscribed().framework_id()); + + event = events.get(); + AWAIT_READY(event); + EXPECT_EQ(Event::OFFERS, event.get().type()); + EXPECT_NE(0, event.get().offers().offers().size()); + + v1::Offer offer = event.get().offers().offers(0); + { + Call call; + call.mutable_framework_id()->CopyFrom(id); + call.set_type(Call::DECLINE); + + Call::Decline* decline = call.mutable_decline(); + decline->add_offer_ids()->CopyFrom(offer.id()); + + // Set 1hr filter to not immediately get another offer. + v1::Filters filters; + filters.set_refuse_seconds(Hours(1).secs()); + decline->mutable_filters()->CopyFrom(filters); + + mesos.send(call); + } + + { + Call call; + call.mutable_framework_id()->CopyFrom(id); + call.set_type(Call::QUIESCE); + + mesos.send(call); + } + + // No offers should be sent within 100 mins because the framework + // quiesced offers. + Clock::pause(); + Clock::advance(Minutes(100)); + Clock::settle(); + + event = events.get(); + ASSERT_TRUE(event.isPending()); + + // On revival the quiescent should be set as false and the scheduler + // should get another offer with same amount of resources. Framework + // should receive offers only after calling reviving offers. + { + Call call; + call.mutable_framework_id()->CopyFrom(id); + call.set_type(Call::REVIVE); + + mesos.send(call); + } + + AWAIT_READY(event); + EXPECT_EQ(Event::OFFERS, event.get().type()); + EXPECT_NE(0, event.get().offers().offers().size()); + ASSERT_EQ(offer.resources(), event.get().offers().offers(0).resources()); + + Shutdown(); // Must shutdown before 'containerizer' gets deallocated. +} + + TEST_P(SchedulerTest, Message) { master::Flags flags = CreateMasterFlags();
