public Subject() { Receive <string>(_ => Context.System.Terminate(), s => "shutdown".Equals(s)); Receive <string>( _ => Sender.Tell(new Tuple <int, IActorRef>(AddressUidExtension.Uid(Context.System), Self)), s => "identify".Equals(s)); }
protected override void OnReceive(object message) { if (message.Equals("getuid")) { Sender.Tell(AddressUidExtension.Uid(Context.System)); } }
public RemoteWatcherSpec(ITestOutputHelper output) : base(@" akka { loglevel = INFO log-dead-letters-during-shutdown = false actor.provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" remote.dot-netty.tcp = { hostname = localhost port = 0 } }", output) { _remoteSystem = ActorSystem.Create("RemoteSystem", Sys.Settings.Config); _remoteAddress = _remoteSystem.AsInstanceOf <ExtendedActorSystem>().Provider.DefaultAddress; var remoteAddressUid = AddressUidExtension.Uid(_remoteSystem); //TODO: Mute dead letters? /* * Seq(system, remoteSystem).foreach(muteDeadLetters( * akka.remote.transport.AssociationHandle.Disassociated.getClass, * akka.remote.transport.ActorTransportAdapter.DisassociateUnderlying.getClass)(_)) */ _heartbeatRspB = new RemoteWatcher.HeartbeatRsp(remoteAddressUid); }
public Subject() { Receive <string>(str => str == "shutdown", c => Context.System.Terminate()); Receive <string>(str => str == "identify", c => { Sender.Tell((AddressUidExtension.Uid(Context.System), Self)); });
public RemoteDeploySpec() : base(@" akka { loglevel = INFO log-dead-letters-during-shutdown = false // actor.provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" remote.helios.tcp = { hostname = localhost port = 0 } actor.deployment { /router1 { router = round-robin-pool nr-of-instances = 3 } /router2 { router = round-robin-pool nr-of-instances = 3 } /router3 { router = round-robin-pool nr-of-instances = 0 } } } ") { _remoteSystem = ActorSystem.Create("RemoteSystem", Sys.Settings.Config); _remoteAddress = _remoteSystem.AsInstanceOf <ExtendedActorSystem>().Provider.DefaultAddress; var remoteAddressUid = AddressUidExtension.Uid(_remoteSystem); }
/// <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 void AddressUidExtension_should_always_report_same_value() { var values = new ConcurrentBag <int>(); var parallelOps = 1000; var loop = Parallel.For(0, parallelOps, i => { values.Add(AddressUidExtension.Uid(Sys)); }); SpinWait.SpinUntil(() => loop.IsCompleted); Assert.True(values.All(x => x == AddressUidExtension.Uid(Sys))); }
public void AddressUidExtension_should_report_different_values_for_different_ActorSystems() { var sys2 = ActorSystem.Create("Sys2"); try { var uid1 = AddressUidExtension.Uid(Sys); var uid2 = AddressUidExtension.Uid(sys2); Assert.NotEqual(uid1, uid2); } finally { sys2.Terminate().Wait(); } }
private void CreateOutboundStateActor(Address remoteAddress, TaskCompletionSource <AssociationHandle> statusPromise, int?refuseUid) { var stateActorLocalAddress = localAddress; var stateActorSettings = _settings; var stateActorWrappedTransport = _wrappedTransport; var failureDetector = CreateTransportFailureDetector(); //TODO: eventually this needs to be configured with the RemoteDispatcher via https://github.com/akka/akka/blob/f1edf789798dc02dfa37d3301d7712736c964ab1/akka-remote/src/main/scala/akka/remote/transport/AkkaProtocolTransport.scala#L156 Context.ActorOf(ProtocolStateActor.OutboundProps( new HandshakeInfo(stateActorLocalAddress, AddressUidExtension.Uid(Context.System)), remoteAddress, statusPromise, stateActorWrappedTransport, stateActorSettings, new AkkaPduProtobuffCodec(), failureDetector, refuseUid), ActorNameFor(remoteAddress)); }
static async Task Main(string[] args) { // launch seed node var seed = StartNode(9444); var pbm = PetabridgeCmd.Get(seed); pbm.RegisterCommandPalette(ClusterCommands.Instance); pbm.Start(); var settings = new SocketLeakDetectorSettings(maxPorts: 20000); var leakDetector = seed.ActorOf(Props.Create(() => new TcpPortUseSupervisor(settings, new[] { IPAddress.Loopback })), "portMonitor"); // start node that will be quarantined var quarantineNode = StartNode(9555); var node2Addr = Cluster.Get(quarantineNode).SelfAddress; var uid = AddressUidExtension.Uid(quarantineNode); var peanutGallery = Enumerable.Repeat(1, 3).Select(x => StartNode(0)).ToList(); Func <int, bool> checkMembers = i => Cluster.Get(seed).State.Members.Count == i; seed.Log.Info("Waiting for members to join..."); while (!checkMembers(5)) { await Task.Delay(TimeSpan.FromSeconds(2)); } seed.Log.Info("Cluster up."); //Console.WriteLine("Press enter to begin quarantine."); //Console.ReadLine(); RarpFor(seed).Quarantine(node2Addr, uid); await Task.Delay(TimeSpan.FromSeconds(2.5)); seed.ActorSelection(new RootActorPath(node2Addr) / "user" / "silence").Tell("fuber"); //Console.WriteLine("Press enter to terminate quarantined node"); //Console.ReadLine(); //await quarantineNode.Terminate(); seed.WhenTerminated.Wait(); }
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"); }
protected override void Ready(object message) { message.Match() .With <InboundAssociation>(ia => //need to create an Inbound ProtocolStateActor { var handle = ia.Association; var stateActorLocalAddress = localAddress; var stateActorAssociationListener = associationListener; var stateActorSettings = _settings; var failureDetector = CreateTransportFailureDetector(); //TODO: eventually this needs to be configured with the RemoteDispatcher via https://github.com/akka/akka/blob/f1edf789798dc02dfa37d3301d7712736c964ab1/akka-remote/src/main/scala/akka/remote/transport/AkkaProtocolTransport.scala#L156 Context.ActorOf(ProtocolStateActor.InboundProps( new HandshakeInfo(stateActorLocalAddress, AddressUidExtension.Uid(Context.System)), handle, stateActorAssociationListener, stateActorSettings, new AkkaPduProtobuffCodec(), failureDetector), ActorNameFor(handle.RemoteAddress)); }) .With <AssociateUnderlying>(au => CreateOutboundStateActor(au.RemoteAddress, au.StatusPromise, null)) //need to create an Outbond ProtocolStateActor .With <AssociateUnderlyingRefuseUid>(au => CreateOutboundStateActor(au.RemoteAddress, au.StatusCompletionSource, au.RefuseUid)); }
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); //create supervisor for daemons under path "/system/cluster" _clusterDaemons = system.SystemActorOf(Props.Create(() => new ClusterDaemon(_settings)).WithDeploy(Deploy.Local), "cluster"); //TODO: Pretty sure this is bad and will at least throw aggregateexception possibly worse. _clusterCore = GetClusterCoreRef().Result; _readView = new ClusterReadView(this); }
private void CreateOutboundStateActor(Address remoteAddress, TaskCompletionSource <AssociationHandle> statusPromise, int?refuseUid) { var stateActorLocalAddress = localAddress; var stateActorSettings = _settings; var stateActorWrappedTransport = _wrappedTransport; var failureDetector = CreateTransportFailureDetector(); Context.ActorOf(RARP.For(Context.System).ConfigureDispatcher(ProtocolStateActor.OutboundProps( new HandshakeInfo(stateActorLocalAddress, AddressUidExtension.Uid(Context.System)), remoteAddress, statusPromise, stateActorWrappedTransport, stateActorSettings, new AkkaPduProtobuffCodec(), failureDetector, refuseUid)), ActorNameFor(remoteAddress)); }
protected override void Ready(object message) { message.Match() .With <InboundAssociation>(ia => //need to create an Inbound ProtocolStateActor { var handle = ia.Association; var stateActorLocalAddress = localAddress; var stateActorAssociationListener = associationListener; var stateActorSettings = _settings; var failureDetector = CreateTransportFailureDetector(); Context.ActorOf(RARP.For(Context.System).ConfigureDispatcher(ProtocolStateActor.InboundProps( new HandshakeInfo(stateActorLocalAddress, AddressUidExtension.Uid(Context.System)), handle, stateActorAssociationListener, stateActorSettings, new AkkaPduProtobuffCodec(), failureDetector)), ActorNameFor(handle.RemoteAddress)); }) .With <AssociateUnderlying>(au => CreateOutboundStateActor(au.RemoteAddress, au.StatusPromise, null)) //need to create an Outbound ProtocolStateActor .With <AssociateUnderlyingRefuseUid>(au => CreateOutboundStateActor(au.RemoteAddress, au.StatusCompletionSource, au.RefuseUid)); }
public void Remoting_must_not_leak_actors() { var actorRef = Sys.ActorOf(EchoActor.Props(this, true), "echo"); var echoPath = new RootActorPath(RARP.For(Sys).Provider.DefaultAddress) / "user" / "echo"; var targets = new[] { "/system/endpointManager", "/system/transports" }.Select(x => { Sys.ActorSelection(x).Tell(new Identify(0)); return(ExpectMsg <ActorIdentity>().Subject); }).ToList(); var initialActors = targets.SelectMany(CollectLiveActors).ToImmutableHashSet(); // Clean shutdown case for (var i = 1; i <= 3; i++) { var remoteSystem = ActorSystem.Create("remote", ConfigurationFactory.ParseString("akka.remote.dot-netty.tcp.port = 0") .WithFallback(Sys.Settings.Config)); try { var probe = CreateTestProbe(remoteSystem); remoteSystem.ActorSelection(echoPath).Tell(new Identify(1), probe.Ref); probe.ExpectMsg <ActorIdentity>().Subject.ShouldNotBe(null); } finally { remoteSystem.Terminate(); } remoteSystem.WhenTerminated.Wait(TimeSpan.FromSeconds(10)).ShouldBeTrue(); } // Quarantine an old incarnation case for (var i = 1; i <= 3; i++) { // always use the same address var remoteSystem = ActorSystem.Create("remote", ConfigurationFactory.ParseString("akka.remote.dot-netty.tcp.port = 2553") .WithFallback(Sys.Settings.Config)); try { var remoteAddress = RARP.For(remoteSystem).Provider.DefaultAddress; remoteSystem.ActorOf(Props.Create(() => new StoppableActor()), "stoppable"); // the message from remote to local will cause inbound connection established var probe = CreateTestProbe(remoteSystem); remoteSystem.ActorSelection(echoPath).Tell(new Identify(1), probe.Ref); probe.ExpectMsg <ActorIdentity>().Subject.ShouldNotBe(null); var beforeQuarantineActors = targets.SelectMany(CollectLiveActors).ToImmutableHashSet(); // it must not quarantine the current connection RARP.For(Sys) .Provider.Transport.Quarantine(remoteAddress, AddressUidExtension.Uid(remoteSystem) + 1); // the message from local to remote should reuse passive inbound connection Sys.ActorSelection(new RootActorPath(remoteAddress) / "user" / "stoppable").Tell(new Identify(1)); ExpectMsg <ActorIdentity>().Subject.ShouldNotBe(null); var afterQuarantineActors = targets.SelectMany(CollectLiveActors).ToImmutableHashSet(); AssertActors(beforeQuarantineActors, afterQuarantineActors); } finally { remoteSystem.Terminate(); } remoteSystem.WhenTerminated.Wait(TimeSpan.FromSeconds(10)).ShouldBeTrue(); } // Missing SHUTDOWN case for (var i = 1; i <= 3; i++) { var remoteSystem = ActorSystem.Create("remote", ConfigurationFactory.ParseString("akka.remote.dot-netty.tcp.port = 0") .WithFallback(Sys.Settings.Config)); var remoteAddress = RARP.For(remoteSystem).Provider.DefaultAddress; try { var probe = CreateTestProbe(remoteSystem); remoteSystem.ActorSelection(echoPath).Tell(new Identify(1), probe.Ref); probe.ExpectMsg <ActorIdentity>().Subject.ShouldNotBe(null); // This will make sure that no SHUTDOWN message gets through RARP.For(Sys).Provider.Transport.ManagementCommand(new ForceDisassociate(remoteAddress)) .Wait(TimeSpan.FromSeconds(3)).ShouldBeTrue(); } finally { remoteSystem.Terminate(); } EventFilter.Warning(contains: "Association with remote system").ExpectOne(() => { remoteSystem.WhenTerminated.Wait(TimeSpan.FromSeconds(10)).ShouldBeTrue(); }); } // Remote idle for too long case var idleRemoteSystem = ActorSystem.Create("remote", ConfigurationFactory.ParseString("akka.remote.dot-netty.tcp.port = 0") .WithFallback(Sys.Settings.Config)); var idleRemoteAddress = RARP.For(idleRemoteSystem).Provider.DefaultAddress; idleRemoteSystem.ActorOf(Props.Create <StoppableActor>(), "stoppable"); try { var probe = CreateTestProbe(idleRemoteSystem); idleRemoteSystem.ActorSelection(echoPath).Tell(new Identify(1), probe.Ref); probe.ExpectMsg <ActorIdentity>().Subject.ShouldNotBe(null); // Watch a remote actor - this results in system message traffic Sys.ActorSelection(new RootActorPath(idleRemoteAddress) / "user" / "stoppable").Tell(new Identify(1)); var remoteActor = ExpectMsg <ActorIdentity>().Subject; Watch(remoteActor); remoteActor.Tell("stop"); ExpectTerminated(remoteActor); // All system messages have been acked now on this side // This will make sure that no SHUTDOWN message gets through RARP.For(Sys).Provider.Transport.ManagementCommand(new ForceDisassociate(idleRemoteAddress)) .Wait(TimeSpan.FromSeconds(3)).ShouldBeTrue(); } finally { idleRemoteSystem.Terminate(); } EventFilter.Warning(contains: "Association with remote system").ExpectOne(() => { idleRemoteSystem.WhenTerminated.Wait(TimeSpan.FromSeconds(10)).ShouldBeTrue(); }); /* * Wait for the ReliableDeliverySupervisor to receive its "TooLongIdle" message, * which will throw a HopelessAssociation wrapped around a TimeoutException. */ EventFilter.Exception <TimeoutException>().ExpectOne(() => { }); AwaitAssert(() => { AssertActors(initialActors, targets.SelectMany(CollectLiveActors).ToImmutableHashSet()); }, 5.Seconds()); }