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 2014/08/04 23:52:36 UTC

[4/5] git commit: Handle discards on the master detection futures.

Handle discards on the master detection futures.

Review: https://reviews.apache.org/r/23867


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e20ea630
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e20ea630
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e20ea630

Branch: refs/heads/master
Commit: e20ea63025c158f8377df24650c8ee2c0cabf68c
Parents: 2b5fb07
Author: Benjamin Mahler <bm...@twitter.com>
Authored: Wed Jul 23 15:45:05 2014 -0700
Committer: Benjamin Mahler <bm...@twitter.com>
Committed: Mon Aug 4 13:55:27 2014 -0700

----------------------------------------------------------------------
 src/master/detector.cpp                       | 39 ++++++++++++++++++++++
 src/tests/master_contender_detector_tests.cpp | 33 ++++++++++++++++--
 2 files changed, 70 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e20ea630/src/master/detector.cpp
----------------------------------------------------------------------
diff --git a/src/master/detector.cpp b/src/master/detector.cpp
index 93a6cb2..6436b8e 100644
--- a/src/master/detector.cpp
+++ b/src/master/detector.cpp
@@ -94,6 +94,21 @@ void discard(std::set<Promise<T>* >* promises)
   promises->clear();
 }
 
+
+// Helper for discarding an individual promise in the set.
+template <typename T>
+void discard(std::set<Promise<T>* >* promises, const Future<T>& future)
+{
+  foreach (Promise<T>* promise, *promises) {
+    if (promise->future() == future) {
+      promise->discard();
+      promises->erase(promise);
+      delete promise;
+      return;
+    }
+  }
+}
+
 } // namespace promises {
 
 
@@ -127,11 +142,21 @@ public:
     }
 
     Promise<Option<MasterInfo> >* promise = new Promise<Option<MasterInfo> >();
+
+    promise->future()
+      .onDiscard(defer(self(), &Self::discard, promise->future()));
+
     promises.insert(promise);
     return promise->future();
   }
 
 private:
+  void discard(const Future<Option<MasterInfo> >& future)
+  {
+    // Discard the promise holding this future.
+    promises::discard(&promises, future);
+  }
+
   Option<MasterInfo> leader; // The appointed master.
   set<Promise<Option<MasterInfo> >*> promises;
 };
@@ -149,6 +174,8 @@ public:
   Future<Option<MasterInfo> > detect(const Option<MasterInfo>& previous);
 
 private:
+  void discard(const Future<Option<MasterInfo> >& future);
+
   // Invoked when the group leadership has changed.
   void detected(const Future<Option<Group::Membership> >& leader);
 
@@ -293,6 +320,14 @@ void ZooKeeperMasterDetectorProcess::initialize()
 }
 
 
+void ZooKeeperMasterDetectorProcess::discard(
+    const Future<Option<MasterInfo> >& future)
+{
+  // Discard the promise holding this future.
+  promises::discard(&promises, future);
+}
+
+
 Future<Option<MasterInfo> > ZooKeeperMasterDetectorProcess::detect(
     const Option<MasterInfo>& previous)
 {
@@ -307,6 +342,10 @@ Future<Option<MasterInfo> > ZooKeeperMasterDetectorProcess::detect(
   }
 
   Promise<Option<MasterInfo> >* promise = new Promise<Option<MasterInfo> >();
+
+  promise->future()
+    .onDiscard(defer(self(), &Self::discard, promise->future()));
+
   promises.insert(promise);
   return promise->future();
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/e20ea630/src/tests/master_contender_detector_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_contender_detector_tests.cpp b/src/tests/master_contender_detector_tests.cpp
index 231648d..fdddfa1 100644
--- a/src/tests/master_contender_detector_tests.cpp
+++ b/src/tests/master_contender_detector_tests.cpp
@@ -167,6 +167,16 @@ TEST(BasicMasterContenderDetectorTest, Detector)
   // No one has appointed the leader so we are pending.
   EXPECT_TRUE(detected.isPending());
 
+  // Ensure that the future can be discarded.
+  detected.discard();
+
+  AWAIT_DISCARDED(detected);
+
+  detected = detector.detect();
+
+  // Still no leader appointed yet.
+  EXPECT_TRUE(detected.isPending());
+
   detector.appoint(master);
 
   AWAIT_READY(detected);
@@ -202,7 +212,28 @@ TEST_F(ZooKeeperMasterContenderDetectorTest, MasterContender)
   ZooKeeperMasterDetector detector(url.get());
 
   Future<Option<MasterInfo> > leader = detector.detect();
+
+  AWAIT_READY(leader);
   EXPECT_SOME_EQ(master, leader.get());
+
+  leader = detector.detect(leader.get());
+
+  // No change to leadership.
+  ASSERT_TRUE(leader.isPending());
+
+  // Ensure we can discard the future.
+  leader.discard();
+
+  AWAIT_DISCARDED(leader);
+
+  // After the discard, we can re-detect correctly.
+  leader = detector.detect(None());
+
+  AWAIT_READY(leader);
+  EXPECT_SOME_EQ(master, leader.get());
+
+  // Now test that a session expiration causes candidacy to be lost
+  // and the future to become ready.
   Future<Nothing> lostCandidacy = contended.get();
   leader = detector.detect(leader.get());
 
@@ -210,8 +241,6 @@ TEST_F(ZooKeeperMasterContenderDetectorTest, MasterContender)
   AWAIT_READY(sessionId);
   server->expireSession(sessionId.get().get());
 
-  // Session expiration causes candidacy to be lost and the
-  // Future<Nothing> to be fulfilled.
   AWAIT_READY(lostCandidacy);
   AWAIT_READY(leader);
   EXPECT_NONE(leader.get());