This is an automated email from the ASF dual-hosted git repository. chhsiao pushed a commit to branch 1.8.x in repository https://gitbox.apache.org/repos/asf/mesos.git
commit c889ba6b7818e8eea8b2a11c442bac81b6a237a2 Author: Chun-Hung Hsiao <[email protected]> AuthorDate: Wed May 15 21:54:20 2019 -0700 Notifies master `/api/v1` subscribers about recovered frameworks. If one subscribes to master's `/api/v1` endpoint after a master failover but before an agent reregistration, frameworks recovered through the agent registration should be notified to the subscriber, otherwise recovered tasks will have framework IDs referring to frameworks unknown to the subscriber. Review: https://reviews.apache.org/r/70651 --- src/common/protobuf_utils.cpp | 4 ---- src/master/master.cpp | 7 +++++++ src/tests/api_tests.cpp | 35 +++++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/common/protobuf_utils.cpp b/src/common/protobuf_utils.cpp index 8b252cb..6a93ac7 100644 --- a/src/common/protobuf_utils.cpp +++ b/src/common/protobuf_utils.cpp @@ -1337,10 +1337,6 @@ mesos::master::Event createTaskAdded(const Task& task) mesos::master::Event createFrameworkAdded( const mesos::internal::master::Framework& _framework) { - CHECK(_framework.active()); - CHECK(_framework.connected()); - CHECK(!_framework.recovered()); - mesos::master::Event event; event.set_type(mesos::master::Event::FRAMEWORK_ADDED); diff --git a/src/master/master.cpp b/src/master/master.cpp index 06a89bc..5488b7b 100644 --- a/src/master/master.cpp +++ b/src/master/master.cpp @@ -10521,6 +10521,13 @@ void Master::recoverFramework( Framework* framework = new Framework(this, flags, info); + // Send a `FRAMEWORK_ADDED` event to subscribers before adding recovered tasks + // so the framework ID referred by any succeeding `TASK_ADDED` event will be + // known to subscribers. + if (!subscribers.subscribed.empty()) { + subscribers.send(protobuf::master::event::createFrameworkAdded(*framework)); + } + // Add active operations, tasks, and executors to the framework. foreachvalue (Slave* slave, slaves.registered) { if (slave->tasks.contains(framework->id())) { diff --git a/src/tests/api_tests.cpp b/src/tests/api_tests.cpp index 4850ba6..539c704 100644 --- a/src/tests/api_tests.cpp +++ b/src/tests/api_tests.cpp @@ -2711,8 +2711,9 @@ TEST_P(MasterAPITest, SubscribersReceiveHealthUpdates) // This test verifies that subscribing to the 'api/v1' endpoint between -// a master failover and an agent re-registration won't cause the master -// to crash. See MESOS-8601. +// a master failover and an agent reregistration won't cause the master +// to crash, and frameworks recovered through agent reregistration will be +// broadcast to subscribers. See MESOS-8601 and MESOS-9785. TEST_P(MasterAPITest, MasterFailover) { ContentType contentType = GetParam(); @@ -2863,21 +2864,35 @@ TEST_P(MasterAPITest, MasterFailover) AWAIT_READY(slaveReregisteredMessage); - // The agent re-registration should result in an `AGENT_ADDED` event - // and a `TASK_ADDED` event. - set<v1::master::Event::Type> expectedEvents = - {v1::master::Event::AGENT_ADDED, v1::master::Event::TASK_ADDED}; - set<v1::master::Event::Type> observedEvents; + // The agent re-registration should result in an `AGENT_ADDED` event, + // a `FRAMEWORK_ADDED` event and a `TASK_ADDED` event in order. + event = decoder.read(); + AWAIT_READY(event); + + EXPECT_EQ(v1::master::Event::AGENT_ADDED, event.get()->type()); + const v1::master::Event::AgentAdded& agentAdded = event.get()->agent_added(); + + EXPECT_EQ(agentId, agentAdded.agent().agent_info().id()); event = decoder.read(); AWAIT_READY(event); - observedEvents.insert(event->get().type()); + + EXPECT_EQ(v1::master::Event::FRAMEWORK_ADDED, event.get()->type()); + const v1::master::Event::FrameworkAdded& frameworkAdded = + event.get()->framework_added(); + + EXPECT_EQ(frameworkId, frameworkAdded.framework().framework_info().id()); + EXPECT_FALSE(frameworkAdded.framework().active()); + EXPECT_FALSE(frameworkAdded.framework().connected()); + EXPECT_TRUE(frameworkAdded.framework().recovered()); event = decoder.read(); AWAIT_READY(event); - observedEvents.insert(event->get().type()); - EXPECT_EQ(expectedEvents, observedEvents); + EXPECT_EQ(v1::master::Event::TASK_ADDED, event.get()->type()); + const v1::master::Event::TaskAdded& taskAdded = event.get()->task_added(); + + EXPECT_EQ(task.task_id(), taskAdded.task().task_id()); }
