Exemple #1
0
 public ClusterMembershipService(
     MembershipTableManager membershipTableManager,
     ILogger <ClusterMembershipService> log,
     IFatalErrorHandler fatalErrorHandler)
 {
     this.snapshot = membershipTableManager.MembershipTableSnapshot.CreateClusterMembershipSnapshot();
     this.updates  = new AsyncEnumerable <ClusterMembershipSnapshot>(
         (previous, proposed) => proposed.Version == MembershipVersion.MinValue || proposed.Version > previous.Version,
         this.snapshot)
     {
         OnPublished = update => Interlocked.Exchange(ref this.snapshot, update)
     };
     this.membershipTableManager = membershipTableManager;
     this.log = log;
     this.fatalErrorHandler = fatalErrorHandler;
 }
        /// <summary>
        /// Returns a <see cref="ClusterMembershipUpdate"/> which represents the change in cluster membership from the provided snapshot to this instance.
        /// </summary>
        /// <returns>A <see cref="ClusterMembershipUpdate"/> which represents the change in cluster membership from the provided snapshot to this instance.</returns>
        public ClusterMembershipUpdate CreateUpdate(ClusterMembershipSnapshot previous)
        {
            if (previous is null)
            {
                throw new ArgumentNullException(nameof(previous));
            }
            if (this.Version < previous.Version)
            {
                throw new ArgumentException($"Argument must have a previous version to the current instance. Expected <= {this.Version}, encountered {previous.Version}", nameof(previous));
            }

            if (this.Version == previous.Version)
            {
                return(new ClusterMembershipUpdate(this, ImmutableArray <ClusterMember> .Empty));
            }

            var changes = ImmutableHashSet.CreateBuilder <ClusterMember>();

            foreach (var entry in this.Members)
            {
                // Include any entry which is new or has changed state.
                if (!previous.Members.TryGetValue(entry.Key, out var previousEntry) || previousEntry.Status != entry.Value.Status)
                {
                    changes.Add(entry.Value);
                }
            }

            // Handle entries which were removed entirely.
            foreach (var entry in previous.Members)
            {
                if (!this.Members.TryGetValue(entry.Key, out _))
                {
                    changes.Add(new ClusterMember(entry.Key, SiloStatus.Dead, entry.Value.Name));
                }
            }

            return(new ClusterMembershipUpdate(this, changes.ToImmutableArray()));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClusterMembershipUpdate"/> class.
 /// </summary>
 /// <param name="snapshot">The snapshot.</param>
 /// <param name="changes">The changes.</param>
 public ClusterMembershipUpdate(ClusterMembershipSnapshot snapshot, ImmutableArray <ClusterMember> changes)
 {
     this.Snapshot = snapshot;
     this.Changes  = changes;
 }