+clu #13584 Accept joining to be WeaklyUp during network split

* experimental feature, disabled by default
* Adding documentation to mention weakly up members.
  plus adding new diagram.
This commit is contained in:
Veiga Ortiz, Héctor 2015-08-25 17:20:05 -05:00 committed by Patrik Nordwall
parent 3a436bb4a3
commit c08bc317e2
19 changed files with 329 additions and 45 deletions

View file

@ -0,0 +1,119 @@
/**
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.cluster
import scala.language.postfixOps
import scala.concurrent.duration._
import akka.remote.testkit.MultiNodeConfig
import akka.remote.testkit.MultiNodeSpec
import akka.remote.transport.ThrottlerTransportAdapter.Direction
import akka.testkit._
import com.typesafe.config.ConfigFactory
import akka.cluster.MemberStatus.WeaklyUp
object MemberWeaklyUpSpec extends MultiNodeConfig {
val first = role("first")
val second = role("second")
val third = role("third")
val fourth = role("fourth")
val fifth = role("fifth")
commonConfig(debugConfig(on = false).
withFallback(ConfigFactory.parseString("""
akka.remote.retry-gate-closed-for = 3 s
akka.cluster.allow-weakly-up-members = on
""")).
withFallback(MultiNodeClusterSpec.clusterConfig))
testTransport(on = true)
}
class MemberWeaklyUpMultiJvmNode1 extends MemberWeaklyUpSpec
class MemberWeaklyUpMultiJvmNode2 extends MemberWeaklyUpSpec
class MemberWeaklyUpMultiJvmNode3 extends MemberWeaklyUpSpec
class MemberWeaklyUpMultiJvmNode4 extends MemberWeaklyUpSpec
class MemberWeaklyUpMultiJvmNode5 extends MemberWeaklyUpSpec
abstract class MemberWeaklyUpSpec
extends MultiNodeSpec(MemberWeaklyUpSpec)
with MultiNodeClusterSpec {
import MemberWeaklyUpSpec._
muteMarkingAsUnreachable()
val side1 = Vector(first, second)
val side2 = Vector(third, fourth, fifth)
"A cluster of 3 members" must {
"reach initial convergence" taggedAs LongRunningTest in {
awaitClusterUp(first, third, fourth)
enterBarrier("after-1")
}
"detect network partition and mark nodes on other side as unreachable" taggedAs LongRunningTest in within(20 seconds) {
runOn(first) {
// split the cluster in two parts (first, second) / (third, fourth, fifth)
for (role1 side1; role2 side2) {
testConductor.blackhole(role1, role2, Direction.Both).await
}
}
enterBarrier("after-split")
runOn(first) {
awaitAssert(clusterView.unreachableMembers.map(_.address) should be(Set(address(third), address(fourth))))
}
runOn(third, fourth) {
awaitAssert(clusterView.unreachableMembers.map(_.address) should be(Set(address(first))))
}
enterBarrier("after-2")
}
"accept joining on each side and set status to WeaklyUp" taggedAs LongRunningTest in within(20 seconds) {
runOn(second) {
Cluster(system).join(first)
}
runOn(fifth) {
Cluster(system).join(fourth)
}
enterBarrier("joined")
runOn(side1: _*) {
awaitAssert {
clusterView.members.size should be(4)
clusterView.members.exists { m m.address == address(second) && m.status == WeaklyUp } should be(true)
}
}
runOn(side2: _*) {
awaitAssert {
clusterView.members.size should be(4)
clusterView.members.exists { m m.address == address(fifth) && m.status == WeaklyUp } should be(true)
}
}
enterBarrier("after-3")
}
"change status to Up after healed network partition" taggedAs LongRunningTest in within(20 seconds) {
runOn(first) {
for (role1 side1; role2 side2) {
testConductor.passThrough(role1, role2, Direction.Both).await
}
}
enterBarrier("after-passThrough")
awaitAllReachable()
awaitMembersUp(5)
enterBarrier("after-4")
}
}
}

View file

@ -26,6 +26,17 @@ object MinMembersBeforeUpMultiJvmSpec extends MultiNodeConfig {
withFallback(MultiNodeClusterSpec.clusterConfigWithFailureDetectorPuppet))
}
object MinMembersBeforeUpWithWeaklyUpMultiJvmSpec extends MultiNodeConfig {
val first = role("first")
val second = role("second")
val third = role("third")
commonConfig(debugConfig(on = false).withFallback(ConfigFactory.parseString("""
akka.cluster.min-nr-of-members = 3
akka.cluster.allow-weakly-up-members = on""")).
withFallback(MultiNodeClusterSpec.clusterConfigWithFailureDetectorPuppet))
}
object MinMembersOfRoleBeforeUpMultiJvmSpec extends MultiNodeConfig {
val first = role("first")
val second = role("second")
@ -46,6 +57,10 @@ class MinMembersBeforeUpMultiJvmNode1 extends MinMembersBeforeUpSpec
class MinMembersBeforeUpMultiJvmNode2 extends MinMembersBeforeUpSpec
class MinMembersBeforeUpMultiJvmNode3 extends MinMembersBeforeUpSpec
class MinMembersBeforeUpWithWeaklyUpMultiJvmNode1 extends MinMembersBeforeUpSpec
class MinMembersBeforeUpWithWeaklyUpMultiJvmNode2 extends MinMembersBeforeUpSpec
class MinMembersBeforeUpWithWeaklyUpMultiJvmNode3 extends MinMembersBeforeUpSpec
class MinMembersOfRoleBeforeUpMultiJvmNode1 extends MinMembersOfRoleBeforeUpSpec
class MinMembersOfRoleBeforeUpMultiJvmNode2 extends MinMembersOfRoleBeforeUpSpec
class MinMembersOfRoleBeforeUpMultiJvmNode3 extends MinMembersOfRoleBeforeUpSpec
@ -63,6 +78,19 @@ abstract class MinMembersBeforeUpSpec extends MinMembersBeforeUpBase(MinMembersB
}
}
abstract class MinMembersBeforeUpWithWeaklyUpSpec extends MinMembersBeforeUpBase(MinMembersBeforeUpMultiJvmSpec) {
override def first: RoleName = MinMembersBeforeUpWithWeaklyUpMultiJvmSpec.first
override def second: RoleName = MinMembersBeforeUpWithWeaklyUpMultiJvmSpec.second
override def third: RoleName = MinMembersBeforeUpWithWeaklyUpMultiJvmSpec.third
"Cluster leader" must {
"wait with moving members to UP until minimum number of members have joined with weakly up enabled" taggedAs LongRunningTest in {
testWaitMovingMembersToUp()
}
}
}
abstract class MinMembersOfRoleBeforeUpSpec extends MinMembersBeforeUpBase(MinMembersOfRoleBeforeUpMultiJvmSpec) {
override def first: RoleName = MinMembersOfRoleBeforeUpMultiJvmSpec.first