Beispiel #1
0
 /// <summary>
 /// Sends a command to issue state transition to LEAVING for the node specified by <paramref name="address"/>.
 /// The member will go through the status changes <see cref="MemberStatus.Leaving"/> (not published to
 /// subscribers) followed by <see cref="MemberStatus.Exiting"/> and finally <see cref="MemberStatus.Removed"/>.
 ///
 /// Note that this command can be issued to any member in the cluster, not necessarily the
 /// one that is leaving. The cluster extension, but not the actor system, of the leaving member will be shutdown after
 /// the leader has changed status of the member to <see cref="MemberStatus.Exiting"/>. Thereafter the member will be
 /// removed from the cluster. Normally this is handled automatically, but in case of network failures during
 /// this process it might still be necessary to set the node's status to <see cref="MemberStatus.Down"/> in order
 /// to complete the removal.
 /// </summary>
 /// <param name="address">The address of the node leaving the cluster.</param>
 public void Leave(Address address)
 {
     if (FillLocal(address) == SelfAddress)
     {
         LeaveSelf();
     }
     else
         ClusterCore.Tell(new ClusterUserAction.Leave(FillLocal(address)));
 }
Beispiel #2
0
        /// <summary>
        /// Subscribe to one or more cluster domain events.
        /// </summary>
        /// <param name="subscriber">The actor who'll receive the cluster domain events</param>
        /// <param name="initialStateMode">
        /// If set to <see cref="ClusterEvent.SubscriptionInitialStateMode.InitialStateAsEvents"/>, then the events corresponding to the current state
        /// are sent to <paramref name="subscriber"/> to mimic what it would have seen if it were listening to the events when they occurred in the past.
        ///
        /// If set to <see cref="ClusterEvent.SubscriptionInitialStateMode.InitialStateAsSnapshot"/>, then a snapshot of
        /// <see cref="ClusterEvent.CurrentClusterState"/> will be sent to <paramref name="subscriber"/> as the first message.
        /// </param>
        /// <param name="to">An array of event types that the actor receives.</param>
        /// <exception cref="ArgumentException">
        /// This exception is thrown when the array of supplied types, <paramref name="to"/>, is empty
        /// or contains types that do not implement <see cref="ClusterEvent.IClusterDomainEvent"/>.
        /// </exception>
        public void Subscribe(IActorRef subscriber, ClusterEvent.SubscriptionInitialStateMode initialStateMode, params Type[] to)
        {
            if (to.Length == 0)
                throw new ArgumentException("At least one `IClusterDomainEvent` class is required", nameof(to));
            if (!to.All(t => typeof(ClusterEvent.IClusterDomainEvent).IsAssignableFrom(t)))
                throw new ArgumentException($"Subscribe to `IClusterDomainEvent` or subclasses, was [{string.Join(", ", to.Select(c => c.Name))}]", nameof(to));

            ClusterCore.Tell(new InternalClusterAction.Subscribe(subscriber, initialStateMode, ImmutableHashSet.Create(to)));
        }
Beispiel #3
0
        private Task LeaveSelf()
        {
            var tcs = new TaskCompletionSource<object>();
            var leaveTask = Interlocked.CompareExchange(ref _leaveTask, tcs.Task, null);

            // It's assumed here that once the member left the cluster, it won't get back again.
            // So, the member removal event being memoized in TaskCompletionSource and never reset.
            if (leaveTask != null)
                return leaveTask;

            // Subscribe to MemberRemoved events
            _clusterDaemons.Tell(new InternalClusterAction.AddOnMemberRemovedListener(() => tcs.TrySetResult(null)));

            // Send leave message
            ClusterCore.Tell(new ClusterUserAction.Leave(SelfAddress));

            return tcs.Task;
        }
Beispiel #4
0
 /// <summary>
 /// Sends a command to DOWN the node specified by <paramref name="address"/>.
 ///
 /// When a member is considered by the failure detector to be unreachable the leader is not
 /// allowed to perform its duties, such as changing status of new joining members to <see cref="MemberStatus.Up"/>.
 /// The status of the unreachable member must be changed to <see cref="MemberStatus.Down"/>, which can be done with
 /// this method.
 /// </summary>
 /// <param name="address">The address of the node we're going to mark as <see cref="MemberStatus.Down"/></param>
 public void Down(Address address)
 {
     ClusterCore.Tell(new ClusterUserAction.Down(FillLocal(address)));
 }
Beispiel #5
0
 /// <summary>
 /// Joins the specified seed nodes without defining them in config.
 /// Especially useful from tests when Addresses are unknown before startup time.
 ///
 /// An actor system can only join a cluster once. Additional attempts will be ignored.
 /// When it has successfully joined it must be restarted to be able to join another
 /// cluster or to join the same cluster again.
 /// </summary>
 /// <param name="seedNodes">TBD</param>
 public void JoinSeedNodes(IEnumerable <Address> seedNodes)
 {
     ClusterCore.Tell(
         new InternalClusterAction.JoinSeedNodes(seedNodes.Select(FillLocal).ToImmutableList()));
 }
Beispiel #6
0
 /// <summary>
 /// Try to join this cluster node specified by <paramref name="address"/>.
 /// A <see cref="Join"/> command is sent to the node to join.
 ///
 /// An actor system can only join a cluster once. Additional attempts will be ignored.
 /// When it has successfully joined it must be restarted to be able to join another
 /// cluster or to join the same cluster again.
 /// </summary>
 /// <param name="address">The address of the node we want to join.</param>
 public void Join(Address address)
 {
     ClusterCore.Tell(new ClusterUserAction.JoinTo(FillLocal(address)));
 }
Beispiel #7
0
 /// <summary>
 /// Sends the current (full) state of the cluster to the specified actor.
 /// If you want this to happen periodically, you can use the <see cref="Scheduler"/> to schedule
 /// a call to this method. You can also call <see cref="State"/> directly for this information.
 /// </summary>
 /// <param name="receiver">The actor that receives the current cluster state.</param>
 public void SendCurrentClusterState(IActorRef receiver)
 {
     ClusterCore.Tell(new InternalClusterAction.SendCurrentClusterState(receiver));
 }
Beispiel #8
0
 /// <summary>
 /// Stops the specific actor from receiving a specific type of cluster domain event.
 /// </summary>
 /// <param name="subscriber">The actor that no longer receives cluster domain events.</param>
 /// <param name="to">The event type that the actor no longer receives.</param>
 public void Unsubscribe(IActorRef subscriber, Type to)
 {
     ClusterCore.Tell(new InternalClusterAction.Unsubscribe(subscriber, to));
 }
Beispiel #9
0
 /// <summary>
 /// Send command to issue state transition to LEAVING for the node specified by <paramref name="address"/>.
 /// The member will go through the status changes <see cref="MemberStatus.Leaving"/> (not published to
 /// subscribers) followed by <see cref="MemberStatus.Exiting"/> and finally <see cref="MemberStatus.Removed"/>.
 ///
 /// Note that this command can be issued to any member in the cluster, not necessarily the
 /// one that is leaving. The cluster extension, but not the actor system, of the leaving member will be shutdown after
 /// the leader has changed status of the member to <see cref="MemberStatus.Exiting"/>. Thereafter the member will be
 /// removed from the cluster. Normally this is handled automatically, but in case of network failures during
 /// this process it might still be necessary to set the node's status to <see cref="MemberStatus.Down"/> in order
 /// to complete the removal.
 /// </summary>
 /// <param name="address"></param>
 public void Leave(Address address)
 {
     ClusterCore.Tell(new ClusterUserAction.Leave(FillLocal(address)));
 }