You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2014/01/15 23:02:25 UTC
[4/5] git commit: LeaderContender::withdraw() now always returns
false if there is no membership to withdraw.
LeaderContender::withdraw() now always returns false if there is no
membership to withdraw.
This includes when:
- withdraw() is called before contend()
- withdraw() is called after contend() but before the contender learns that it fails to obtain the candidacy
- withdraw() is called after the contender has learned that it had failed to obtain the candidacy
From: Jiang Yan Xu <ya...@jxu.me>
Review: https://reviews.apache.org/r/16590
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/682b0d99
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/682b0d99
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/682b0d99
Branch: refs/heads/master
Commit: 682b0d9917960fd4f976eb26dc5fdb1d9957c692
Parents: b2516db
Author: Vinod Kone <vi...@twitter.com>
Authored: Wed Jan 15 12:51:49 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jan 15 12:54:58 2014 -0800
----------------------------------------------------------------------
src/tests/zookeeper_tests.cpp | 9 ++++++-
src/zookeeper/contender.cpp | 50 ++++++++++++++++++--------------------
src/zookeeper/contender.hpp | 4 +--
3 files changed, 33 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/682b0d99/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index 94d324a..656afde 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -267,11 +267,18 @@ TEST_F(ZooKeeperTest, LeaderContender)
Owned<LeaderContender> contender(
new LeaderContender(&group, "candidate 1"));
+
+ // Calling withdraw before contending returns 'false' because there
+ // is nothing to withdraw.
+ Future<bool> withdrawn = contender->withdraw();
+ AWAIT_READY(withdrawn);
+ EXPECT_FALSE(withdrawn.get());
+
contender->contend();
// Immediately withdrawing after contending leads to delayed
// cancellation.
- Future<bool> withdrawn = contender->withdraw();
+ withdrawn = contender->withdraw();
AWAIT_READY(withdrawn);
EXPECT_TRUE(withdrawn.get());
http://git-wip-us.apache.org/repos/asf/mesos/blob/682b0d99/src/zookeeper/contender.cpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/contender.cpp b/src/zookeeper/contender.cpp
index e857afa..d8a5201 100644
--- a/src/zookeeper/contender.cpp
+++ b/src/zookeeper/contender.cpp
@@ -40,9 +40,6 @@ private:
// Invoked when the group membership is cancelled.
void cancelled(const Future<bool>& result);
- // Helper for setting error and failing pending promises.
- void fail(const string& message);
-
// Helper for cancelling the Group membership.
void cancel();
@@ -104,8 +101,8 @@ void LeaderContenderProcess::finalize()
{
// We do not wait for the result here because the Group keeps
// retrying (even after the contender is destroyed) until it
- // either succeeds or its session times out. In either case the
- // old membership is eventually cancelled.
+ // succeeds so the old membership is eventually going to be
+ // cancelled.
// There is a tricky situation where the contender terminates after
// it has contended but before it is notified of the obtained
// membership. In this case the membership is not cancelled during
@@ -135,7 +132,8 @@ Future<Future<Nothing> > LeaderContenderProcess::contend()
Future<bool> LeaderContenderProcess::withdraw()
{
if (contending.isNone()) {
- return Failure("Can only withdraw after the contender has contended");
+ // Nothing to withdraw because the contender has not contended.
+ return false;
}
if (withdrawing.isSome()) {
@@ -169,6 +167,9 @@ void LeaderContenderProcess::cancel()
{
if (!candidacy.isReady()) {
// Nothing to cancel.
+ if (withdrawing.isSome()) {
+ withdrawing.get()->set(false);
+ }
return;
}
@@ -191,7 +192,13 @@ void LeaderContenderProcess::cancelled(const Future<bool>& result)
CHECK(!result.isDiscarded());
if (result.isFailed()) {
- fail(result.failure());
+ if (withdrawing.isSome()) {
+ withdrawing.get()->fail(result.failure());
+ }
+
+ if (watching.isSome()) {
+ watching.get()->fail(result.failure());
+ }
} else {
if (withdrawing.isSome()) {
withdrawing.get()->set(result);
@@ -208,13 +215,22 @@ void LeaderContenderProcess::joined()
{
CHECK(!candidacy.isDiscarded());
+ // Cannot be watching because the candidacy is not obtained yet.
+ CHECK(watching.isNone());
+
+ CHECK_SOME(contending);
+
if (candidacy.isFailed()) {
- fail(candidacy.failure());
+ // The promise 'withdrawing' will be set to false in cancel().
+ contending.get()->fail(candidacy.failure());
return;
}
if (withdrawing.isSome()) {
LOG(INFO) << "Joined group after the contender started withdrawing";
+
+ // The promise 'withdrawing' will be set to 'false' in subsequent
+ // 'cancel()' call.
return;
}
@@ -222,11 +238,9 @@ void LeaderContenderProcess::joined()
<< data << "') has entered the contest for leadership";
// Transition to 'watching' state.
- CHECK(watching.isNone());
watching = new Promise<Nothing>();
// Notify the client.
- CHECK_SOME(contending);
if (contending.get()->set(watching.get()->future())) {
// Continue to watch that our membership is not removed (if the
// client still cares about it).
@@ -236,22 +250,6 @@ void LeaderContenderProcess::joined()
}
-void LeaderContenderProcess::fail(const string& message)
-{
- if (contending.isSome()) {
- contending.get()->fail(message);
- }
-
- if (watching.isSome()) {
- watching.get()->fail(message);
- }
-
- if (withdrawing.isSome()) {
- withdrawing.get()->fail(message);
- }
-}
-
-
LeaderContender::LeaderContender(Group* group, const string& data)
{
process = new LeaderContenderProcess(group, data);
http://git-wip-us.apache.org/repos/asf/mesos/blob/682b0d99/src/zookeeper/contender.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/contender.hpp b/src/zookeeper/contender.hpp
index f45c0df..e526e2d 100644
--- a/src/zookeeper/contender.hpp
+++ b/src/zookeeper/contender.hpp
@@ -45,11 +45,9 @@ public:
// Returns true if successfully withdrawn from the contest (either
// while contending or has already contended and is watching for
// membership loss).
- // It should only be called after contend() is called, otherwise a
- // failure is returned.
// A false return value implies that there was no valid group
// membership to cancel, which may be a result of a race to cancel
- // an expired membership.
+ // an expired membership or because there is nothing to withdraw.
// A failed future is returned if the contender is unable to
// withdraw.
process::Future<bool> withdraw();