public override void Start() { log.Info("Starting remoting"); if (_endpointManager == null) { _endpointManager = System.SystemActorOf( Props.Create(() => new EndpointManager(Provider.Config, log)).WithDeploy(Deploy.Local), EndpointManagerName); try { var addressPromise = new TaskCompletionSource <IList <ProtocolTransportAddressPair> >(); _endpointManager.Tell(new EndpointManager.Listen(addressPromise)); addressPromise.Task.Wait(Provider.RemoteSettings.StartupTimeout); var akkaProtocolTransports = addressPromise.Task.Result; Addresses = new HashSet <Address>(akkaProtocolTransports.Select(a => a.Address)); // this.transportMapping = akkaProtocolTransports // .ToDictionary(p => p.ProtocolTransport.Transport.SchemeIdentifier,); IEnumerable <IGrouping <string, ProtocolTransportAddressPair> > tmp = akkaProtocolTransports.GroupBy(t => t.ProtocolTransport.SchemeIdentifier); _transportMapping = new Dictionary <string, HashSet <ProtocolTransportAddressPair> >(); foreach (var g in tmp) { var set = new HashSet <ProtocolTransportAddressPair>(g); _transportMapping.Add(g.Key, set); } _defaultAddress = akkaProtocolTransports.Head().Address; _addresses = new HashSet <Address>(akkaProtocolTransports.Select(x => x.Address)); log.Info("Remoting started; listening on addresses : [{0}]", string.Join(",", _addresses.Select(x => x.ToString()))); _endpointManager.Tell(new EndpointManager.StartupFinished()); _eventPublisher.NotifyListeners(new RemotingListenEvent(_addresses.ToList())); } catch (TaskCanceledException ex) { NotifyError("Startup was cancelled due to timeout", ex); throw; } catch (TimeoutException ex) { NotifyError("Startup timed out", ex); throw; } catch (Exception ex) { NotifyError("Startup failed", ex); throw; } } else { log.Warn("Remoting was already started. Ignoring start attempt."); } }
protected override SupervisorStrategy SupervisorStrategy() { return(new OneForOneStrategy(ex => { var directive = Directive.Stop; ex.Match() .With <InvalidAssociation>(ia => { log.Warning("Tried to associate with unreachable remote address [{0}]. " + "Address is now gated for {1} ms, all messages to this address will be delivered to dead letters. Reason: [{2}]", ia.RemoteAddress, settings.RetryGateClosedFor.TotalMilliseconds, ia.Message); endpoints.MarkAsFailed(Sender, Deadline.Now + settings.RetryGateClosedFor); AddressTerminatedTopic.Get(Context.System).Publish(new AddressTerminated(ia.RemoteAddress)); directive = Directive.Stop; }) .With <ShutDownAssociation>(shutdown => { log.Debug("Remote system with address [{0}] has shut down. " + "Address is not gated for {1}ms, all messages to this address will be delivered to dead letters.", shutdown.RemoteAddress, settings.RetryGateClosedFor.TotalMilliseconds); endpoints.MarkAsFailed(Sender, Deadline.Now + settings.RetryGateClosedFor); AddressTerminatedTopic.Get(Context.System).Publish(new AddressTerminated(shutdown.RemoteAddress)); directive = Directive.Stop; }) .With <HopelessAssociation>(hopeless => { if (settings.QuarantineDuration.HasValue && hopeless.Uid.HasValue) { endpoints.MarkAsQuarantined(hopeless.RemoteAddress, hopeless.Uid.Value, Deadline.Now + settings.QuarantineDuration.Value); eventPublisher.NotifyListeners(new QuarantinedEvent(hopeless.RemoteAddress, hopeless.Uid.Value)); } else { log.Warning("Association to [{0}] with unknown UID is irrecoverably failed. " + "Address cannot be quarantined without knowing the UID, gating instead for {1} ms.", hopeless.RemoteAddress, settings.RetryGateClosedFor.TotalMilliseconds); endpoints.MarkAsFailed(Sender, Deadline.Now + settings.RetryGateClosedFor); } AddressTerminatedTopic.Get(Context.System).Publish(new AddressTerminated(hopeless.RemoteAddress)); directive = Directive.Stop; }) .Default(msg => { if (msg is EndpointDisassociatedException || msg is EndpointAssociationException) { } //no logging else { log.Error(ex, ex.Message); } }); return directive; })); }
/// <summary> /// Start assumes that it cannot be followed by another Start() without having a Shutdown() first /// </summary> /// <exception cref="ConfigurationException"> /// This exception is thrown when no transports are enabled under the "akka.remote.enabled-transports" configuration setting. /// </exception> /// <exception cref="TaskCanceledException"> /// This exception is thrown when startup is canceled due to a timeout. /// </exception> /// <exception cref="TimeoutException"> /// This exception is thrown when startup times out. /// </exception> /// <exception cref="Exception"> /// This exception is thrown when a general error occurs during startup. /// </exception> public override void Start() { if (_endpointManager == null) { _log.Info("Starting remoting"); _endpointManager = System.SystemActorOf(RARP.For(System).ConfigureDispatcher( Props.Create(() => new EndpointManager(System.Settings.Config, _log)).WithDeploy(Deploy.Local)), EndpointManagerName); try { var addressPromise = new TaskCompletionSource <IList <ProtocolTransportAddressPair> >(); // tells the EndpointManager to start all transports and bind them to listenable addresses, and then set the results // of this promise to include them. _endpointManager.Tell(new EndpointManager.Listen(addressPromise)); addressPromise.Task.Wait(Provider.RemoteSettings.StartupTimeout); var akkaProtocolTransports = addressPromise.Task.Result; if (akkaProtocolTransports.Count == 0) { throw new ConfigurationException(@"No transports enabled under ""akka.remote.enabled-transports"""); } _addresses = new HashSet <Address>(akkaProtocolTransports.Select(a => a.Address)); IEnumerable <IGrouping <string, ProtocolTransportAddressPair> > tmp = akkaProtocolTransports.GroupBy(t => t.ProtocolTransport.SchemeIdentifier); _transportMapping = new Dictionary <string, HashSet <ProtocolTransportAddressPair> >(); foreach (var g in tmp) { var set = new HashSet <ProtocolTransportAddressPair>(g); _transportMapping.Add(g.Key, set); } _defaultAddress = akkaProtocolTransports.Head().Address; _addresses = new HashSet <Address>(akkaProtocolTransports.Select(x => x.Address)); _log.Info("Remoting started; listening on addresses : [{0}]", string.Join(",", _addresses.Select(x => x.ToString()))); _endpointManager.Tell(new EndpointManager.StartupFinished()); _eventPublisher.NotifyListeners(new RemotingListenEvent(_addresses.ToList())); } catch (TaskCanceledException ex) { NotifyError("Startup was canceled due to timeout", ex); throw; } catch (TimeoutException ex) { NotifyError("Startup timed out", ex); throw; } catch (Exception ex) { NotifyError("Startup failed", ex); throw; } } else { _log.Warning("Remoting was already started. Ignoring start attempt."); } }
protected override SupervisorStrategy SupervisorStrategy() { return(new OneForOneStrategy(ex => { var directive = Directive.Stop; ex.Match() .With <InvalidAssociation>(ia => { KeepQuarantinedOr(ia.RemoteAddress, () => { var causedBy = ia.InnerException == null ? "" : string.Format("Caused by: [{0}]", ia.InnerException); _log.Warning("Tried to associate with unreachable remote address [{0}]. Address is now gated for {1} ms, all messages to this address will be delivered to dead letters. Reason: [{2}] {3}", ia.RemoteAddress, _settings.RetryGateClosedFor.TotalMilliseconds, ia.Message, causedBy); _endpoints.MarkAsFailed(Sender, Deadline.Now + _settings.RetryGateClosedFor); }); if (ia.DisassociationInfo.HasValue && ia.DisassociationInfo == DisassociateInfo.Quarantined) { //TODO: add context.system.eventStream.publish(ThisActorSystemQuarantinedEvent(localAddress, remoteAddress)) } directive = Directive.Stop; }) .With <ShutDownAssociation>(shutdown => { KeepQuarantinedOr(shutdown.RemoteAddress, () => { _log.Debug("Remote system with address [{0}] has shut down. Address is now gated for {1}ms, all messages to this address will be delivered to dead letters.", shutdown.RemoteAddress, _settings.RetryGateClosedFor.TotalMilliseconds); _endpoints.MarkAsFailed(Sender, Deadline.Now + _settings.RetryGateClosedFor); }); directive = Directive.Stop; }) .With <HopelessAssociation>(hopeless => { if (hopeless.Uid.HasValue) { _log.Error("Association to [{0}] with UID [{1}] is irrecoverably failed. Quarantining address.", hopeless.RemoteAddress, hopeless.Uid); if (_settings.QuarantineDuration.HasValue) { _endpoints.MarkAsQuarantined(hopeless.RemoteAddress, hopeless.Uid.Value, Deadline.Now + _settings.QuarantineDuration.Value); _eventPublisher.NotifyListeners(new QuarantinedEvent(hopeless.RemoteAddress, hopeless.Uid.Value)); } } else { _log.Warning("Association to [{0}] with unknown UID is irrecoverably failed. Address cannot be quarantined without knowing the UID, gating instead for {1} ms.", hopeless.RemoteAddress, _settings.RetryGateClosedFor.TotalMilliseconds); _endpoints.MarkAsFailed(Sender, Deadline.Now + _settings.RetryGateClosedFor); } directive = Directive.Stop; }) .Default(msg => { if (msg is EndpointDisassociatedException || msg is EndpointAssociationException) { } //no logging else { _log.Error(ex, ex.Message); } _endpoints.MarkAsFailed(Sender, Deadline.Now + _settings.RetryGateClosedFor); directive = Directive.Stop; }); return directive; })); }