Fixes according review. See #3076

This commit is contained in:
Björn Antonsson 2013-03-08 13:26:50 +01:00
parent 386bf87f0e
commit 7ed6b3d4ee
6 changed files with 19 additions and 26 deletions

View file

@ -65,10 +65,6 @@ akka {
# Probability value is between 0.0 and 1.0. 0.0 means never, 1.0 means always. # Probability value is between 0.0 and 1.0. 0.0 means never, 1.0 means always.
gossip-different-view-probability = 0.8 gossip-different-view-probability = 0.8
# Limit number of merge conflicts per second that are handled. If the limit is
# exceeded the conflicting gossip messages are dropped and will reappear later.
max-gossip-merge-rate = 5.0
# Settings for the Phi accrual failure detector (http://ddg.jaist.ac.jp/pub/HDY+04.pdf # Settings for the Phi accrual failure detector (http://ddg.jaist.ac.jp/pub/HDY+04.pdf
# [Hayashibara et al]) used by the cluster subsystem to detect unreachable members. # [Hayashibara et al]) used by the cluster subsystem to detect unreachable members.
failure-detector { failure-detector {

View file

@ -540,8 +540,8 @@ private[cluster] final class ClusterCoreDaemon(publisher: ActorRef) extends Acto
latestGossip = winningGossip seen selfAddress latestGossip = winningGossip seen selfAddress
// for all new joining nodes we remove them from the failure detector // for all new joining nodes we remove them from the failure detector
(latestGossip.members -- localGossip.members).foreach { latestGossip.members foreach {
node if (node.status == Joining) failureDetector.remove(node.address) node if (node.status == Joining && !localGossip.members(node)) failureDetector.remove(node.address)
} }
log.debug("Cluster Node [{}] - Receiving gossip from [{}]", selfAddress, from) log.debug("Cluster Node [{}] - Receiving gossip from [{}]", selfAddress, from)

View file

@ -59,7 +59,6 @@ class ClusterSettings(val config: Config, val systemName: String) {
case id id case id id
} }
final val GossipDifferentViewProbability: Double = cc.getDouble("gossip-different-view-probability") final val GossipDifferentViewProbability: Double = cc.getDouble("gossip-different-view-probability")
final val MaxGossipMergeRate: Double = cc.getDouble("max-gossip-merge-rate")
final val SchedulerTickDuration: FiniteDuration = Duration(cc.getMilliseconds("scheduler.tick-duration"), MILLISECONDS) final val SchedulerTickDuration: FiniteDuration = Duration(cc.getMilliseconds("scheduler.tick-duration"), MILLISECONDS)
final val SchedulerTicksPerWheel: Int = cc.getInt("scheduler.ticks-per-wheel") final val SchedulerTicksPerWheel: Int = cc.getInt("scheduler.ticks-per-wheel")
final val MetricsEnabled: Boolean = cc.getBoolean("metrics.enabled") final val MetricsEnabled: Boolean = cc.getBoolean("metrics.enabled")

View file

@ -120,17 +120,21 @@ private[cluster] case class Gossip(
overview.seen.get(address).exists(_ == version) overview.seen.get(address).exists(_ == version)
} }
private def mergeSeenTables(allowed: immutable.Set[Member], one: Map[Address, VectorClock], another: Map[Address, VectorClock]): Map[Address, VectorClock] = { private def mergeSeenTables(allowed: Set[Member], one: Map[Address, VectorClock], another: Map[Address, VectorClock]): Map[Address, VectorClock] = {
(one.filter { case (a, v) allowed.exists(_.address == a) } /: another) { (Map.empty[Address, VectorClock] /: allowed) {
case (merged, (address, oneVersion)) (merged, member)
if (allowed.exists(_.address == address)) { val address = member.address
val anotherVersion = merged.getOrElse(address, oneVersion) (one.get(address), another.get(address)) match {
anotherVersion tryCompareTo oneVersion match { case (None, None) merged
case None merged - address case (Some(v1), None) merged.updated(address, v1)
case Some(x) if x > 0 merged + (address -> anotherVersion) case (None, Some(v2)) merged.updated(address, v2)
case _ merged + (address -> oneVersion) case (Some(v1), Some(v2))
} v1 tryCompareTo v2 match {
} else merged case None merged
case Some(x) if x > 0 merged.updated(address, v1)
case _ merged.updated(address, v2)
}
}
} }
} }
@ -169,19 +173,14 @@ private[cluster] case class Gossip(
* @return true if convergence have been reached and false if not * @return true if convergence have been reached and false if not
*/ */
def convergence: Boolean = { def convergence: Boolean = {
val unreachable = overview.unreachable
val seen = overview.seen
// First check that: // First check that:
// 1. we don't have any members that are unreachable, or // 1. we don't have any members that are unreachable, or
// 2. all unreachable members in the set have status DOWN // 2. all unreachable members in the set have status DOWN
// Else we can't continue to check for convergence // Else we can't continue to check for convergence
// When that is done we check that all members exists in the seen table and // When that is done we check that all members exists in the seen table and
// have the latest vector clock version // have the latest vector clock version
val hasUnreachable = unreachable.nonEmpty && unreachable.exists { _.status != Down }
def allMembersInSeenHasLatest = members.forall(m seen.get(m.address).exists(_ == version))
!hasUnreachable && allMembersInSeenHasLatest overview.unreachable.forall(_.status == Down) && members.forall(m seenByAddress(m.address))
} }
def isLeader(address: Address): Boolean = leader == Some(address) def isLeader(address: Address): Boolean = leader == Some(address)

View file

@ -84,7 +84,7 @@ object StressMultiJvmSpec extends MultiNodeConfig {
normal-throughput-duration = 30s normal-throughput-duration = 30s
high-throughput-duration = 10s high-throughput-duration = 10s
supervision-duration = 10s supervision-duration = 10s
supervision-one-iteration = 1s supervision-one-iteration = 2.5s
expected-test-duration = 600s expected-test-duration = 600s
# actors are created in a tree structure defined # actors are created in a tree structure defined
# by tree-width (number of children for each actor) and # by tree-width (number of children for each actor) and

View file

@ -42,7 +42,6 @@ class ClusterConfigSpec extends AkkaSpec {
JmxEnabled must be(true) JmxEnabled must be(true)
UseDispatcher must be(Dispatchers.DefaultDispatcherId) UseDispatcher must be(Dispatchers.DefaultDispatcherId)
GossipDifferentViewProbability must be(0.8 plusOrMinus 0.0001) GossipDifferentViewProbability must be(0.8 plusOrMinus 0.0001)
MaxGossipMergeRate must be(5.0 plusOrMinus 0.0001)
SchedulerTickDuration must be(33 millis) SchedulerTickDuration must be(33 millis)
SchedulerTicksPerWheel must be(512) SchedulerTicksPerWheel must be(512)
MetricsEnabled must be(true) MetricsEnabled must be(true)