public void HandleFailure(ISupervisor supervisor, PID child, RestartStatistics rs, Exception cause, object message)
        {
            if (ShouldStop(rs))
            {
                _logger.LogWarning($"Stopping {child.ToShortString()} connection to address {_address} after retries expired Reason {cause}");
                _cancelFutureRetries.Cancel();
                supervisor.StopChildren(child);
                ProcessRegistry.Instance.Remove(child); //TODO: work out why this hangs around in the process registry

                var terminated = new EndpointTerminatedEvent
                {
                    Address = _address
                };
                Actor.EventStream.Publish(terminated);

                //Reset everything to original values
                _backoff             = config.EndpointWriterOptions.RetryBackOffms;
                _cancelFutureRetries = new CancellationTokenSource();
            }
            else
            {
                _backoff = _backoff * 2;
                var noise    = _random.Next(_backoff);
                var duration = TimeSpan.FromMilliseconds(_backoff + noise);
                Task.Delay(duration).ContinueWith(t =>
                {
                    _logger.LogWarning($"Restarting {child.ToShortString()} for {_address} after {duration} Reason {cause}");
                    supervisor.RestartChildren(cause, child);
                }, _cancelFutureRetries.Token);
            }
        }
示例#2
0
        private void Notify(MemberStatus @new, MemberStatus old)
        {
            if (@new == null && old == null)
            {
                return; //ignore
            }

            if (@new == null)
            {
                //notify left
                var left = new MemberLeftEvent(old.Host, old.Port, old.Kinds);
                Actor.EventStream.Publish(left);
                _members.Remove(old.Address);
                var endpointTerminated = new EndpointTerminatedEvent
                {
                    Address = old.Address
                };
                Actor.EventStream.Publish(endpointTerminated);

                return;
            }

            if (old == null)
            {
                //notify joined
                var joined = new MemberJoinedEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(joined);
                return;
            }

            if (@new.MemberId != old.MemberId)
            {
                var rejoined = new MemberRejoinedEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(rejoined);
                return;
            }

            if (old.Alive && [email protected])
            {
                var unavailable = new MemberUnavailableEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(unavailable);
                return;
            }

            if (@new.Alive && !old.Alive)
            {
                var available = new MemberAvailableEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(available);
            }
        }
        private static void UpdateAndNotify(MemberStatus @new, MemberStatus old)
        {
            if (@new == null && old == null)
            {
                return; //ignore
            }

            if (@new == null)
            {
                //update MemberStrategy
                foreach (var k in old.Kinds)
                {
                    if (MemberStrategyByKind.TryGetValue(k, out var ms))
                    {
                        ms.RemoveMember(old);
                        if (ms.GetAllMembers().Count == 0)
                        {
                            MemberStrategyByKind.Remove(k);
                        }
                    }
                }

                //notify left
                var left = new MemberLeftEvent(old.Host, old.Port, old.Kinds);
                Actor.EventStream.Publish(left);
                Members.Remove(old.Address);
                var endpointTerminated = new EndpointTerminatedEvent
                {
                    Address = old.Address
                };
                Actor.EventStream.Publish(endpointTerminated);
                return;
            }

            if (old == null)
            {
                //update MemberStrategy
                foreach (var k in @new.Kinds)
                {
                    if (!MemberStrategyByKind.ContainsKey(k))
                    {
                        MemberStrategyByKind[k] = Cluster.Config.MemberStrategyBuilder(k);
                    }
                    MemberStrategyByKind[k].AddMember(@new);
                }

                //notify joined
                var joined = new MemberJoinedEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(joined);
                return;
            }

            //update MemberStrategy
            if (@new.Alive != old.Alive || @new.MemberId != old.MemberId || @new.StatusValue != null && [email protected](old.StatusValue))
            {
                foreach (var k in @new.Kinds)
                {
                    if (MemberStrategyByKind.TryGetValue(k, out var ms))
                    {
                        ms.UpdateMember(@new);
                    }
                }
            }

            //notify changes
            if (@new.MemberId != old.MemberId)
            {
                var rejoined = new MemberRejoinedEvent(@new.Host, @new.Port, @new.Kinds);
                Actor.EventStream.Publish(rejoined);
            }
        }