private async Task HeartBeatLoop()
        {
            await Task.Yield();

            while (!_cluster.System.Shutdown.IsCancellationRequested)
            {
                try
                {
                    await Task.Delay(_cluster.Config.HeartBeatInterval);

                    var members = _cluster.MemberList.GetAllMembers();

                    foreach (var member in members)
                    {
                        var pid = PID.FromAddress(member.Address, ClusterHeartBeatName);

                        try
                        {
                            await _context.RequestAsync <HeartbeatResponse>(pid, new HeartbeatRequest(),
                                                                            TimeSpan.FromSeconds(5)
                                                                            );

                            _logger.LogDebug("Heartbeat request for member id {MemberId} Address {Address} succeeded",
                                             member.Id, member.Address
                                             );
                        }
                        catch (TimeoutException)
                        {
                            if (_cluster.System.Shutdown.IsCancellationRequested)
                            {
                                return;
                            }

                            _logger.LogWarning("Heartbeat request for member id {MemberId} Address {Address} timed out",
                                               member.Id, member.Address
                                               );
                        }
                        catch (DeadLetterException)
                        {
                            if (_cluster.System.Shutdown.IsCancellationRequested)
                            {
                                return;
                            }

                            _logger.LogWarning(
                                "Heartbeat request for member id {MemberId} Address {Address} got dead letter response",
                                member.Id, member.Address
                                );
                        }
                    }
                }
                catch (Exception x)
                {
                    _logger.LogError(x, "Heartbeat loop failed");
                }
            }
        }
        public async Task <StoredActivation?> TryGetExistingActivation(
            ClusterIdentity clusterIdentity,
            CancellationToken ct
            )
        {
            var pidLookup = await LookupKey(GetKey(clusterIdentity), ct);

            return(pidLookup?.Address == null || pidLookup?.UniqueIdentity == null
                ? null
                : new StoredActivation(pidLookup.MemberId !,
                                       PID.FromAddress(pidLookup.Address, pidLookup.UniqueIdentity)
                                       ));
        }
        private void Invalidate(ClusterIdentity identity, PID activation, BitArray activeRemotes)
        {
            var message = new ActivationTerminated
            {
                ClusterIdentity = identity,
                Pid             = activation
            };
            var remotesToInvalidate = Cluster.MemberList.GetAllMembers()
                                      .Select(m => Cluster.MemberList.GetMetaMember(m.Id))
                                      .Where(m => activeRemotes.Length > m.Index && activeRemotes[m.Index])
                                      .Select(m => m.Member.Address);

            foreach (var address in remotesToInvalidate)
            {
                Cluster.System.Root.Send(PID.FromAddress(address, ActorName), message);
            }
        }
 static PID ActivatorForAddress(string address) => PID.FromAddress(address, "activator");
Beispiel #5
0
        public override async Task Receive(
            IAsyncStreamReader <MessageBatch> requestStream,
            IServerStreamWriter <Unit> responseStream,
            ServerCallContext context
            )
        {
            using var cancellationTokenRegistration = _endpointManager.CancellationToken.Register(() => {
                Logger.LogDebug("[EndpointReader] Telling to {Address} to stop", context.Peer);

                try
                {
                    _ = responseStream.WriteAsync(new Unit());
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "[EndpointReader] Didn't tell to {Address} to stop", context.Peer);
                }
            }
                                                                                                  );

            var targets = new PID[100];

            while (await requestStream.MoveNext(context.CancellationToken).ConfigureAwait(false))
            {
                if (_endpointManager.CancellationToken.IsCancellationRequested)
                {
                    // We read all the messages ignoring them to gracefully end the request
                    continue;
                }

                var batch = requestStream.Current;

                // Logger.LogDebug("[EndpointReader] Received a batch of {Count} messages from {Remote}",
                //     batch.TargetNames.Count, context.Peer
                // );

                //only grow pid lookup if needed
                if (batch.TargetNames.Count > targets.Length)
                {
                    targets = new PID[batch.TargetNames.Count];
                }

                for (var i = 0; i < batch.TargetNames.Count; i++)
                {
                    var pid = PID.FromAddress(_system.Address, batch.TargetNames[i]);
                    pid.Ref(_system);
                    targets[i] = pid;
                }

                var typeNames = batch.TypeNames.ToArray();

                var m = _system.Metrics.Get <RemoteMetrics>().RemoteDeserializedMessageCount;

                foreach (var envelope in batch.Envelopes)
                {
                    var target = targets[envelope.Target];

                    if (envelope.RequestId != default)
                    {
                        target = target.WithRequestId(envelope.RequestId);
                    }
                    var typeName = typeNames[envelope.TypeId];

                    if (!_system.Metrics.IsNoop)
                    {
                        m.Inc(new[] { _system.Id, _system.Address, typeName });
                    }

                    object message;

                    try
                    {
                        message =
                            _serialization.Deserialize(typeName, envelope.MessageData, envelope.SerializerId);

                        //translate from on-the-wire representation to in-process representation
                        //this only applies to root level messages, and never on nested child messages
                        if (message is IRootSerialized serialized)
                        {
                            message = serialized.Deserialize(_system);
                        }
                    }
                    catch (Exception)
                    {
                        Logger.Log(_deserializationErrorLogLevel, "[EndpointReader] Unable to deserialize message with {Type} from {Remote}",
                                   typeName, context.Peer
                                   );
                        continue;
                    }

                    switch (message)
                    {
                    case Terminated msg:
                        Terminated(msg, target);
                        break;

                    case SystemMessage sys:
                        SystemMessage(sys, target);
                        break;

                    default:
                        ReceiveMessages(envelope, message, target);
                        break;
                    }
                }
            }

            _system.Metrics.Get <RemoteMetrics>().RemoteEndpointDisconnectedCount.Inc(new[] { _system.Id, _system.Address, context.Peer });
            Logger.LogDebug("[EndpointReader] Stream closed by {Remote}", context.Peer);
        }
Beispiel #6
0
 // ReSharper disable once SuggestBaseTypeForParameter
 private PID Activate(Member activator, ClusterIdentity identity) =>
 PID.FromAddress(activator.Address, $"placement-activator/{identity}${NextId()}");