Disallow re-joining, see #2873

* Disallow join requests when already part of a cluster
* Remove wipe state when joining, since join can only be
  performed from empty state
* When trying to join, only accept gossip from that member
* Ignore gossips from unknown (and unreachable) members
* Make sure received gossip contains selfAddress
* Test join of fresh node with same host:port
* Remove JoinTwoClustersSpec
* Welcome message as reply to Join
* Retry unsucessful join request
* AddressUidExtension
* Uid in cluster Member identifier
  To be able to distinguish nodes with same host:port
  after restart.
* Ignore gossip with wrong uid
* Renamed Remove command to Shutdown
* Use uid in vclock identifier
* Update sample, Member apply is private
* Disabled config duration syntax and cleanup of io settings
* Update documentation
This commit is contained in:
Patrik Nordwall 2013-04-11 09:18:12 +02:00
parent cdf717e855
commit 9e56ab6fe5
35 changed files with 795 additions and 546 deletions

View file

@ -22,34 +22,39 @@ class ClusterMessageSerializerSpec extends AkkaSpec {
import MemberStatus._
val a1 = Member(Address("akka.tcp", "sys", "a", 2552), Joining, Set.empty)
val b1 = Member(Address("akka.tcp", "sys", "b", 2552), Up, Set("r1"))
val c1 = Member(Address("akka.tcp", "sys", "c", 2552), Leaving, Set("r2"))
val d1 = Member(Address("akka.tcp", "sys", "d", 2552), Exiting, Set("r1", "r2"))
val e1 = Member(Address("akka.tcp", "sys", "e", 2552), Down, Set("r3"))
val f1 = Member(Address("akka.tcp", "sys", "f", 2552), Removed, Set("r2", "r3"))
val a1 = TestMember(Address("akka.tcp", "sys", "a", 2552), Joining, Set.empty)
val b1 = TestMember(Address("akka.tcp", "sys", "b", 2552), Up, Set("r1"))
val c1 = TestMember(Address("akka.tcp", "sys", "c", 2552), Leaving, Set("r2"))
val d1 = TestMember(Address("akka.tcp", "sys", "d", 2552), Exiting, Set("r1", "r2"))
val e1 = TestMember(Address("akka.tcp", "sys", "e", 2552), Down, Set("r3"))
val f1 = TestMember(Address("akka.tcp", "sys", "f", 2552), Removed, Set("r2", "r3"))
"ClusterMessages" must {
"be serializable" in {
val address = Address("akka.tcp", "system", "some.host.org", 4711)
checkSerialization(ClusterUserAction.Join(address, Set("foo", "bar")))
val uniqueAddress = UniqueAddress(address, 17)
val address2 = Address("akka.tcp", "system", "other.host.org", 4711)
val uniqueAddress2 = UniqueAddress(address2, 18)
checkSerialization(InternalClusterAction.Join(uniqueAddress, Set("foo", "bar")))
checkSerialization(ClusterUserAction.Leave(address))
checkSerialization(ClusterUserAction.Down(address))
checkSerialization(InternalClusterAction.InitJoin)
checkSerialization(InternalClusterAction.InitJoinAck(address))
checkSerialization(InternalClusterAction.InitJoinNack(address))
checkSerialization(ClusterLeaderAction.Exit(address))
checkSerialization(ClusterLeaderAction.Remove(address))
checkSerialization(ClusterLeaderAction.Exit(uniqueAddress))
checkSerialization(ClusterLeaderAction.Shutdown(uniqueAddress))
checkSerialization(ClusterHeartbeatReceiver.Heartbeat(address))
checkSerialization(ClusterHeartbeatReceiver.EndHeartbeat(address))
checkSerialization(ClusterHeartbeatSender.HeartbeatRequest(address))
val node1 = VectorClock.Node("node1")
val node2 = VectorClock.Node("node2")
val g1 = (Gossip(SortedSet(a1, b1, c1, d1)) :+ node1).seen(a1.address).seen(b1.address)
val g2 = (g1 :+ node2).seen(a1.address).seen(c1.address)
checkSerialization(GossipEnvelope(a1.address, g2.copy(overview = g2.overview.copy(unreachable = Set(e1, f1)))))
val g1 = (Gossip(SortedSet(a1, b1, c1, d1)) :+ node1).seen(a1.uniqueAddress).seen(b1.uniqueAddress)
val g2 = (g1 :+ node2).seen(a1.uniqueAddress).seen(c1.uniqueAddress)
checkSerialization(GossipEnvelope(a1.uniqueAddress, uniqueAddress2, g2.copy(overview = g2.overview.copy(unreachable = Set(e1, f1)))))
checkSerialization(InternalClusterAction.Welcome(uniqueAddress, g2))
val mg = MetricsGossip(Set(NodeMetrics(a1.address, 4711, Set(Metric("foo", 1.2, None))),
NodeMetrics(b1.address, 4712, Set(Metric("foo", 2.1, Some(EWMA(value = 100.0, alpha = 0.18))),