Avoid publication of duplicate UnreachableDataCenter, #24955
* see scenario in added test, extracted from debug logs "New gossip published" from MultiDcSplitBrainSpec * it publised UnreachableDataCenter even though it had already published that, when a new cross link is added as unreachable in the reachability table * don't know why the implementation of diffUnreachableDataCenter/isReachable was so complicated, but no tests are failing for the changed implementation
This commit is contained in:
parent
9a9e21a62b
commit
cf4c954009
3 changed files with 81 additions and 11 deletions
|
|
@ -437,14 +437,13 @@ object ClusterEvent {
|
|||
/**
|
||||
* Internal API
|
||||
*/
|
||||
private[cluster] def isReachable(state: MembershipState, oldUnreachableNodes: Set[UniqueAddress])(
|
||||
otherDc: DataCenter): Boolean = {
|
||||
private[cluster] def isDataCenterReachable(state: MembershipState)(otherDc: DataCenter): Boolean = {
|
||||
val unrelatedDcNodes = state.latestGossip.members.collect {
|
||||
case m if m.dataCenter != otherDc && m.dataCenter != state.selfDc => m.uniqueAddress
|
||||
}
|
||||
|
||||
val reachabilityForOtherDc = state.dcReachabilityWithoutObservationsWithin.remove(unrelatedDcNodes)
|
||||
reachabilityForOtherDc.allUnreachable.filterNot(oldUnreachableNodes).isEmpty
|
||||
reachabilityForOtherDc.allUnreachable.isEmpty
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -457,11 +456,11 @@ object ClusterEvent {
|
|||
else {
|
||||
val otherDcs = (oldState.latestGossip.allDataCenters
|
||||
.union(newState.latestGossip.allDataCenters)) - newState.selfDc
|
||||
otherDcs
|
||||
.filterNot(isReachable(newState, oldState.dcReachability.allUnreachableOrTerminated))
|
||||
.iterator
|
||||
.map(UnreachableDataCenter)
|
||||
.to(immutable.IndexedSeq)
|
||||
|
||||
val oldUnreachableDcs = otherDcs.filterNot(isDataCenterReachable(oldState))
|
||||
val currentUnreachableDcs = otherDcs.filterNot(isDataCenterReachable(newState))
|
||||
|
||||
currentUnreachableDcs.diff(oldUnreachableDcs).iterator.map(UnreachableDataCenter).to(immutable.IndexedSeq)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -476,8 +475,8 @@ object ClusterEvent {
|
|||
val otherDcs = (oldState.latestGossip.allDataCenters
|
||||
.union(newState.latestGossip.allDataCenters)) - newState.selfDc
|
||||
|
||||
val oldUnreachableDcs = otherDcs.filterNot(isReachable(oldState, Set()))
|
||||
val currentUnreachableDcs = otherDcs.filterNot(isReachable(newState, Set()))
|
||||
val oldUnreachableDcs = otherDcs.filterNot(isDataCenterReachable(oldState))
|
||||
val currentUnreachableDcs = otherDcs.filterNot(isDataCenterReachable(newState))
|
||||
|
||||
oldUnreachableDcs.diff(currentUnreachableDcs).iterator.map(ReachableDataCenter).to(immutable.IndexedSeq)
|
||||
}
|
||||
|
|
@ -620,7 +619,7 @@ private[cluster] final class ClusterDomainEventPublisher
|
|||
|
||||
val unreachableDataCenters: Set[DataCenter] =
|
||||
if (!membershipState.latestGossip.isMultiDc) Set.empty
|
||||
else membershipState.latestGossip.allDataCenters.filterNot(isReachable(membershipState, Set.empty))
|
||||
else membershipState.latestGossip.allDataCenters.filterNot(isDataCenterReachable(membershipState))
|
||||
|
||||
val state = new CurrentClusterState(
|
||||
members = membershipState.latestGossip.members,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue