/// <summary> /// Initializes a new instance of the <see cref="Cluster"/> class. /// </summary> /// <param name="system">The actor system that hosts the cluster.</param> /// <exception cref="ConfigurationException"> /// This exception is thrown if the <paramref name="system"/> does not have a <see cref="ClusterActorRefProvider"/> enabled in the configuration. /// </exception> public Cluster(ActorSystemImpl system) { System = system; Settings = new ClusterSettings(system.Settings.Config, system.Name); if (!(system.Provider is IClusterActorRefProvider provider)) { throw new ConfigurationException( $"ActorSystem {system} needs to have a 'IClusterActorRefProvider' enabled in the configuration, currently uses {system.Provider.GetType().FullName}"); } SelfUniqueAddress = new UniqueAddress(provider.Transport.DefaultAddress, AddressUidExtension.Uid(system)); _log = Logging.GetLogger(system, "Cluster"); CurrentInfoLogger = new InfoLogger(_log, Settings, SelfAddress); LogInfo("Starting up..."); var clusterCoreTaskSource = new TaskCompletionSource <IActorRef>(); _clusterCoreTask = clusterCoreTaskSource.Task; FailureDetector = new DefaultFailureDetectorRegistry <Address>(() => FailureDetectorLoader.Load(Settings.FailureDetectorImplementationClass, Settings.FailureDetectorConfig, system)); Scheduler = CreateScheduler(system); // it has to be lazy - otherwise if downing provider will init a cluster itself, it will deadlock _downingProvider = new Lazy <IDowningProvider>(() => Akka.Cluster.DowningProvider.Load(Settings.DowningProviderType, system), LazyThreadSafetyMode.ExecutionAndPublication); //create supervisor for daemons under path "/system/cluster" _clusterDaemons = system.SystemActorOf(Props.Create(() => new ClusterDaemon(Settings)).WithDeploy(Deploy.Local), "cluster"); _readView = new ClusterReadView(this); // force the underlying system to start _ = Task.Run(async() => { try { _clusterCore = await _clusterDaemons.Ask <IActorRef>(new InternalClusterAction.GetClusterCoreRef(this), System.Settings.CreationTimeout).ConfigureAwait(false); clusterCoreTaskSource.SetResult(_clusterCore); system.RegisterOnTermination(Shutdown); LogInfo("Started up successfully"); } catch (Exception ex) { _log.Error(ex, "Failed to startup Cluster. You can try to increase 'akka.actor.creation-timeout'."); Shutdown(); System.DeadLetters.Tell(ex); //don't re-throw the error. Just log it. _clusterCore = System.DeadLetters; clusterCoreTaskSource.SetResult(_clusterCore); } }); }
public Cluster(ActorSystemImpl system) { System = system; Settings = new ClusterSettings(system.Settings.Config, system.Name); var provider = system.Provider as ClusterActorRefProvider; if (provider == null) { throw new ConfigurationException( String.Format("ActorSystem {0} needs to have a 'ClusterActorRefProvider' enabled in the configuration, currently uses {1}", system, system.Provider.GetType().FullName)); } SelfUniqueAddress = new UniqueAddress(provider.Transport.DefaultAddress, AddressUidExtension.Uid(system)); _log = Logging.GetLogger(system, "Cluster"); LogInfo("Starting up..."); _failureDetector = new DefaultFailureDetectorRegistry <Address>(() => FailureDetectorLoader.Load(Settings.FailureDetectorImplementationClass, Settings.FailureDetectorConfig, system)); _scheduler = CreateScheduler(system); // it has to be lazy - otherwise if downing provider will init a cluster itself, it will deadlock _downingProvider = new Lazy <IDowningProvider>(() => Akka.Cluster.DowningProvider.Load(Settings.DowningProviderType, system), LazyThreadSafetyMode.ExecutionAndPublication); //create supervisor for daemons under path "/system/cluster" _clusterDaemons = system.SystemActorOf(Props.Create(() => new ClusterDaemon(Settings)).WithDeploy(Deploy.Local), "cluster"); _readView = new ClusterReadView(this); // force the underlying system to start _clusterCore = GetClusterCoreRef().Result; system.RegisterOnTermination(Shutdown); LogInfo("Started up successfully"); }