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));
 }
Beispiel #2
0
 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);
        }
Beispiel #6
0
        /// <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);
                }
            });
        }
Beispiel #7
0
        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)));
        }
Beispiel #8
0
        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();
            }
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        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();
        }
Beispiel #11
0
        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");
        }
Beispiel #12
0
 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));
 }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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));
        }
Beispiel #15
0
 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));
 }
Beispiel #16
0
        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());
        }