/// <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))); }
/// <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))); }
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; }
/// <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))); }
/// <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())); }
/// <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))); }
/// <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)); }
/// <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)); }
/// <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))); }