Ejemplo n.º 1
0
 private void PublishDiff(MembershipState oldState, MembershipState newState, Action <object> pub)
 {
     foreach (var @event in ClusterEvent.DiffMemberEvents(oldState, newState))
     {
         pub(@event);
     }
     foreach (var @event in ClusterEvent.DiffUnreachable(oldState, newState))
     {
         pub(@event);
     }
     foreach (var @event in ClusterEvent.DiffReachable(oldState, newState))
     {
         pub(@event);
     }
     foreach (var @event in ClusterEvent.DiffLeader(oldState, newState))
     {
         pub(@event);
     }
     foreach (var @event in ClusterEvent.DiffRolesLeader(oldState, newState))
     {
         pub(@event);
     }
     // publish internal SeenState for testing purposes
     foreach (var @event in ClusterEvent.DiffSeen(oldState, newState))
     {
         pub(@event);
     }
     foreach (var @event in ClusterEvent.DiffReachability(oldState, newState))
     {
         pub(@event);
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Compares two <see cref="Gossip"/> instances and uses them to publish the appropriate <see cref="IMemberEvent"/>
        /// for any given change to the membership of the current cluster.
        /// </summary>
        /// <param name="oldState">The previous gossip instance.</param>
        /// <param name="newState">The new gossip instance.</param>
        /// <returns>A possibly empty set of membership events to be published to all subscribers.</returns>
        internal static ImmutableList <IMemberEvent> DiffMemberEvents(MembershipState oldState, MembershipState newState)
        {
            if (ReferenceEquals(newState, oldState))
            {
                return(ImmutableList <IMemberEvent> .Empty);
            }

            var newMembers = newState.Members.Except(oldState.Members);

            var membersGroupedByAddress = newState.Members
                                          .Concat(oldState.Members)
                                          .GroupBy(m => m.UniqueAddress);

            var changedMembers = membersGroupedByAddress
                                 .Where(g => g.Count() == 2 &&
                                        (g.First().Status != g.Skip(1).First().Status ||
                                         g.First().UpNumber != g.Skip(1).First().UpNumber))
                                 .Select(g => g.First());

            var memberEvents   = CollectMemberEvents(newMembers.Union(changedMembers));
            var removedMembers = oldState.Members.Except(newState.Members);
            var removedEvents  = removedMembers.Select(m => new MemberRemoved(m.Copy(status: MemberStatus.Removed), m.Status));

            return(memberEvents.Concat(removedEvents).ToImmutableList());
        }
Ejemplo n.º 3
0
        private void PublishChanges(MembershipState newState)
        {
            var oldState = _membershipState;

            // keep the latest state to be sent to new subscribers
            _membershipState = newState;
            PublishDiff(oldState, newState, Publish);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// INTERNAL API
        /// </summary>
        internal static ImmutableList <ReachabilityChanged> DiffReachability(MembershipState oldState, MembershipState newState)
        {
            if (newState.Overview.Reachability.Equals(oldState.Overview.Reachability))
            {
                return(ImmutableList <ReachabilityChanged> .Empty);
            }

            return(ImmutableList.Create(new ReachabilityChanged(newState.Overview.Reachability)));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// INTERNAL API
        /// </summary>
        internal static ImmutableList <LeaderChanged> DiffLeader(MembershipState oldState, MembershipState newState)
        {
            var newLeader = newState.Leader;

            if (newLeader == oldState.Leader)
            {
                return(ImmutableList <LeaderChanged> .Empty);
            }

            return(ImmutableList.Create(new LeaderChanged(newLeader?.Address)));
        }
Ejemplo n.º 6
0
 private static IEnumerable <RoleLeaderChanged> InternalDiffRolesLeader(MembershipState oldState, MembershipState newState)
 {
     foreach (var role in oldState.LatestGossip.AllRoles.Union(newState.LatestGossip.AllRoles))
     {
         var newLeader = newState.RoleLeader(role);
         if (newLeader != oldState.RoleLeader(role))
         {
             yield return(new RoleLeaderChanged(role, newLeader?.Address));
         }
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Default constructor for ClusterDomainEventPublisher.
        /// </summary>
        public ClusterDomainEventPublisher()
        {
            _eventStream     = Context.System.EventStream;
            _membershipState = _emptyMembershipState;

            Receive <InternalClusterAction.PublishChanges>(p => PublishChanges(p.NewState));
            Receive <ClusterEvent.CurrentInternalStats>(currentStats => PublishInternalStats(currentStats));
            Receive <InternalClusterAction.SendCurrentClusterState>(receiver => SendCurrentClusterState(receiver.Receiver));
            Receive <InternalClusterAction.Subscribe>(sub => Subscribe(sub.Subscriber, sub.InitialStateMode, sub.To));
            Receive <InternalClusterAction.Unsubscribe>(unsub => Unsubscribe(unsub.Subscriber, unsub.To));
            Receive <InternalClusterAction.PublishEvent>(evt => Publish(evt));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// INTERNAL API
        /// </summary>
        internal static ImmutableList <ReachableMember> DiffReachable(MembershipState oldState, MembershipState newState)
        {
            if (ReferenceEquals(newState, oldState))
            {
                return(ImmutableList <ReachableMember> .Empty);
            }

            return(oldState.Overview.Reachability.AllUnreachable
                   .Where(node => newState.LatestGossip.HasMember(node) && newState.Overview.Reachability.IsReachable(node) &&
                          !node.Equals(newState.SelfUniqueAddress))
                   .Select(node => new ReachableMember(newState.LatestGossip.GetMember(node)))
                   .ToImmutableList());
        }
Ejemplo n.º 9
0
        /// <summary>
        /// INTERNAL API
        /// </summary>
        internal static ImmutableList <UnreachableMember> DiffUnreachable(MembershipState oldState, MembershipState newState)
        {
            if (ReferenceEquals(newState, oldState))
            {
                return(ImmutableList <UnreachableMember> .Empty);
            }

            var oldUnreachableNodes = oldState.Overview.Reachability.AllUnreachableOrTerminated;

            return(newState.Overview.Reachability.AllUnreachableOrTerminated
                   .Where(node => !oldUnreachableNodes.Contains(node) && !node.Equals(newState.SelfUniqueAddress))
                   .Select(node => new UnreachableMember(newState.LatestGossip.GetMember(node)))
                   .ToImmutableList());
        }
Ejemplo n.º 10
0
        /// <summary>
        /// INTERNAL API
        /// </summary>
        internal static ImmutableList <SeenChanged> DiffSeen(MembershipState oldState, MembershipState newState)
        {
            if (ReferenceEquals(newState, oldState))
            {
                return(ImmutableList <SeenChanged> .Empty);
            }

            var newConvergence = newState.Convergence(ImmutableHashSet <UniqueAddress> .Empty);
            var newSeenBy      = newState.LatestGossip.SeenBy;

            if (!newConvergence.Equals(oldState.Convergence(ImmutableHashSet <UniqueAddress> .Empty)) || !newSeenBy.SequenceEqual(oldState.LatestGossip.SeenBy))
            {
                return(ImmutableList.Create(new SeenChanged(newConvergence, newSeenBy.Select(s => s.Address).ToImmutableHashSet())));
            }

            return(ImmutableList <SeenChanged> .Empty);
        }
Ejemplo n.º 11
0
 private void ClearState()
 {
     _membershipState = _emptyMembershipState;
 }
Ejemplo n.º 12
0
 /// <summary>
 /// INTERNAL API
 /// </summary>
 internal static ImmutableHashSet <RoleLeaderChanged> DiffRolesLeader(MembershipState oldState, MembershipState newState)
 {
     return(InternalDiffRolesLeader(oldState, newState).ToImmutableHashSet());
 }