Akka.Remote.EndpointManager.Accepting C# (CSharp) Метод

Accepting() защищенный Метод

Message-processing behavior when the EndpointManager is able to accept inbound association requests.
protected Accepting ( ) : void
Результат void
        protected void Accepting()
        {
            Receive<ManagementCommand>(mc =>
                {
                    /*
                     * applies a management command to all available transports.
                     * 
                     * Useful for things like global restart 
                     */
                    var sender = Sender;
                    var allStatuses = _transportMapping.Values.Select(x => x.ManagementCommand(mc.Cmd));
                    Task.WhenAll(allStatuses)
                        .ContinueWith(x =>
                        {
                            return new ManagementCommandAck(x.Result.All(y => y));
                        }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)
                        .PipeTo(sender);
                });

            Receive<Quarantine>(quarantine =>
            {
                    //Stop writers
                    var policy =
                    Tuple.Create(_endpoints.WritableEndpointWithPolicyFor(quarantine.RemoteAddress), quarantine.Uid);
                if (policy.Item1 is Pass && policy.Item2 == null)
                {
                    var endpoint = policy.Item1.AsInstanceOf<Pass>().Endpoint;
                    Context.Stop(endpoint);
                    _log.Warning("Association to [{0}] with unknown UID is reported as quarantined, but " +
                    "address cannot be quarantined without knowing the UID, gating instead for {1} ms.", quarantine.RemoteAddress, _settings.RetryGateClosedFor.TotalMilliseconds);
                    _endpoints.MarkAsFailed(endpoint, Deadline.Now + _settings.RetryGateClosedFor);
                }
                else if (policy.Item1 is Pass && policy.Item2 != null)
                {
                    var pass = policy.Item1 as Pass;
                    if (pass.Uid == quarantine.Uid)
                        Context.Stop(pass.Endpoint);
                }
                else
                {
                        // Do nothing, because either:
                        // A: we don't know yet the UID of the writer, it will be checked against current quarantine state later
                        // B: we know the UID, but it does not match with the UID to be quarantined
                    }

                    // Stop inbound read-only associations
                    var readPolicy = Tuple.Create(_endpoints.ReadOnlyEndpointFor(quarantine.RemoteAddress), quarantine.Uid);
                if (readPolicy.Item1?.Item1 != null && quarantine.Uid == null)
                    Context.Stop(readPolicy.Item1.Item1);
                else if (readPolicy.Item1?.Item1 != null && quarantine.Uid != null && readPolicy.Item1?.Item2 == quarantine.Uid) { Context.Stop(readPolicy.Item1.Item1); }
                else { } // nothing to stop

                    Func<AkkaProtocolHandle, bool> matchesQuarantine = handle => handle.RemoteAddress.Equals(quarantine.RemoteAddress) &&
                                                                             quarantine.Uid == handle.HandshakeInfo.Uid;

                    // Stop all matching pending read handoffs
                    _pendingReadHandoffs = _pendingReadHandoffs.Where(x =>
                {
                    var drop = matchesQuarantine(x.Value);
                        // Side-effecting here
                        if (drop)
                    {
                        x.Value.Disassociate();
                        Context.Stop(x.Key);
                    }
                    return !drop;
                }).ToDictionary(key => key.Key, value => value.Value);

                    // Stop all matching stashed connections
                    _stashedInbound = _stashedInbound.Select(x =>
                {
                    var associations = x.Value.Where(assoc =>
                    {
                        var handle = assoc.Association.AsInstanceOf<AkkaProtocolHandle>();
                        var drop = matchesQuarantine(handle);
                        if (drop)
                            handle.Disassociate();
                        return !drop;
                    }).ToList();
                    return new KeyValuePair<IActorRef, List<InboundAssociation>>(x.Key, associations);
                }).ToDictionary(k => k.Key, v => v.Value);

                if (quarantine.Uid.HasValue)
                {
                    _endpoints.MarkAsQuarantined(quarantine.RemoteAddress, quarantine.Uid.Value, Deadline.Now + _settings.QuarantineDuration);
                    _eventPublisher.NotifyListeners(new QuarantinedEvent(quarantine.RemoteAddress, quarantine.Uid.Value));
                }
            });

            Receive<Send>(send =>
            {
                var recipientAddress = send.Recipient.Path.Address;
                Func<int?, IActorRef> createAndRegisterWritingEndpoint = refuseUid => _endpoints.RegisterWritableEndpoint(recipientAddress,
                    CreateEndpoint(recipientAddress, send.Recipient.LocalAddressToUse,
                        _transportMapping[send.Recipient.LocalAddressToUse], _settings, writing: true,
                        handleOption: null, refuseUid: refuseUid), uid: null, refuseUid: refuseUid);

                // pattern match won't throw a NullReferenceException if one is returned by WritableEndpointWithPolicyFor
                _endpoints.WritableEndpointWithPolicyFor(recipientAddress).Match()
                    .With<Pass>(
                        pass =>
                        {
                            pass.Endpoint.Tell(send);
                        })
                    .With<Gated>(gated =>
                    {
                        if (gated.TimeOfRelease.IsOverdue) createAndRegisterWritingEndpoint(null).Tell(send);
                        else Context.System.DeadLetters.Tell(send);
                    })
                    .With<Quarantined>(quarantined =>
                    {
                            // timeOfRelease is only used for garbage collection reasons, therefore it is ignored here. We still have
                            // the Quarantined tombstone and we know what UID we don't want to accept, so use it.
                            createAndRegisterWritingEndpoint(quarantined.Uid).Tell(send);
                    })
                    .Default(msg => createAndRegisterWritingEndpoint(null).Tell(send));
            });
            Receive<InboundAssociation>(ia => HandleInboundAssociation(ia, false));
            Receive<EndpointWriter.StoppedReading>(endpoint => AcceptPendingReader(endpoint.Writer));
            Receive<Terminated>(terminated =>
            {
                AcceptPendingReader(terminated.ActorRef);
                _endpoints.UnregisterEndpoint(terminated.ActorRef);
                HandleStashedInbound(terminated.ActorRef, writerIsIdle: false);
            });
            Receive<EndpointWriter.TookOver>(tookover => RemovePendingReader(tookover.Writer, tookover.ProtocolHandle));
            Receive<ReliableDeliverySupervisor.GotUid>(gotuid =>
            {
                _endpoints.RegisterWritableEndpointUid(gotuid.RemoteAddress, gotuid.Uid);
                HandleStashedInbound(Sender, writerIsIdle: false);
            });
            Receive<ReliableDeliverySupervisor.Idle>(idle =>
            {
                HandleStashedInbound(Sender, writerIsIdle: true);
            });
            Receive<Prune>(prune => _endpoints.Prune());
            Receive<ShutdownAndFlush>(shutdown =>
            {
                    //Shutdown all endpoints and signal to Sender when ready (and whether all endpoints were shutdown gracefully)
                    var sender = Sender;

                    // The construction of the Task for shutdownStatus has to happen after the flushStatus future has been finished
                    // so that endpoints are shut down before transports.
                    var shutdownStatus = Task.WhenAll(_endpoints.AllEndpoints.Select(
                        x => x.GracefulStop(_settings.FlushWait, EndpointWriter.FlushAndStop.Instance))).ContinueWith(
                            result =>
                            {
                                if (result.IsFaulted || result.IsCanceled)
                                {
                                    if (result.Exception != null)
                                        result.Exception.Handle(e => true);
                                    return false;
                                }
                                return result.Result.All(x => x);
                            }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);

                shutdownStatus.ContinueWith(tr => Task.WhenAll(_transportMapping.Values.Select(x => x.Shutdown())).ContinueWith(
                          result =>
                          {
                              if (result.IsFaulted || result.IsCanceled)
                              {
                                  if (result.Exception != null)
                                      result.Exception.Handle(e => true);
                                  return false;
                              }
                              return result.Result.All(x => x) && tr.Result;
                          }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)).Unwrap().PipeTo(sender);


                foreach (var handoff in _pendingReadHandoffs.Values)
                {
                    handoff.Disassociate(DisassociateInfo.Shutdown);
                }

                    //Ignore all other writes
                    _normalShutdown = true;
                Become(Flushing);
            });
        }