Akka.net 경로의user

32152 단어
이색구를 자주 사는데 매번 복권 번호가 귀찮아서 쉬는 시간에 이색구 당첨 프로그램을 만들었는데 업무가 복잡하다는 것을 알고 DDD로 디자인을 바꾸고 서비스를 나누며 여러 가지 고생을 했습니다.그러나 이것은 이 수필과 그다지 큰 관계가 없으니, 차이가 얼마 남지 않았으니 다시 한 번 총결하여 틈이 나면 써라.
위에서 서비스 철거를 말했듯이 입력, 당첨, 당첨 등 세 가지 서비스로 분리했다. 세 가지 서비스는 처음에 메시지 대기열을 사용했지만 나중에 서비스 분야의 대상 간의 상호작용이라는 것을 발견했다. Actor를 연상했다. 대상을 대상으로 하면 모든 것이 대상이고 actor도 모든 것이 actor이다. 보고 있으면 집안이 맞기 때문에 메시지 대기열을 해치운다.세부 사항은 나중에 기회가 되면 다시 이야기하자.
위쪽도 사실 이 수필과 아무런 관계가 없다. 관계가 있는 것은 시간 관계로akka의 문서를 이해하지 못했기 때문에 서버 연결 주소의'user'가 어디에서 왔는지 궁금하다.
//var section = (AkkaConfigurationSection)ConfigurationManager.GetSection("akka");
//using (var system = ActorSystem.Create("TestClient", section.AkkaConfig))
            using (var system = ActorSystem.Create("TestClient"))
            {
                var actor = system.ActorSelection("akka.tcp://TestServer@localhost:8081/user/tester");

                while (true)
                {
                    var input = Console.ReadLine();
                    if (input.Equals("1"))
                    {
                        actor.Tell(new DTO("11111"));
                    }
                    else if (input.Equals("2"))
                    {
                        actor.Tell(new DTO("22222"));
                    }
                    else
                    {
                        actor.Tell(new DTO("H W"));
                    }
                }
            }

위에는 클라이언트, 아래에는 서버:
 1             var config = ConfigurationFactory.ParseString(@"
 2             akka {  
 3                 actor {
 4                     provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
 5                 }
 6                 remote {
 7                     helios.tcp {
 8                         transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
 9                         applied-adapters = []
10                         transport-protocol = tcp
11                         port = 8081
12                         hostname = localhost
13                     }
14                 }
15             }
16             ");
17 
18             using (var system = ActorSystem.Create("TestServer", config))
19             {
20                 system.ActorOf<TestDTOActor>("tester");
21 
22                 Console.ReadLine();
23             }

문서가 많을 거예요. 최근에 다른 볼 게 있어서 코드를 생각해 봤어요. 어차피 당분간 생산 환경에 쓰이지 않을 거예요. 그때 가서 얘기해요. 궁금한 문제부터 해결할게요.
그래서 먼저 ActorSystem의 실현 클래스인 ActorSystem Impl, 시스템입니다.ActorOf("tester")가 서버 경로에 미치는 영향은 다음과 같습니다.
        public override IActorRef SystemActorOf<TActor>(string name = null)
        {
            return _provider.SystemGuardian.Cell.ActorOf<TActor>(name);
        }

그래서 찾아봐provider:
        public ActorSystemImpl(string name, Config config)
        {
            if(!Regex.Match(name, "^[a-zA-Z0-9][a-zA-Z0-9-]*$").Success)
                throw new ArgumentException(
                    "invalid ActorSystem name [" + name +
                    "], must contain only word characters (i.e. [a-zA-Z0-9] plus non-leading '-')");
            if(config == null)
                throw new ArgumentNullException("config");

            _name = name;            
            ConfigureSettings(config);
            ConfigureEventStream();
            ConfigureProvider();
            ConfigureTerminationCallbacks();
            ConfigureScheduler();
            ConfigureSerialization();
            ConfigureMailboxes();
            ConfigureDispatchers();
            ConfigureActorProducerPipeline();
        }

        private void ConfigureSettings(Config config)
        {
            _settings = new Settings(this, config);
        }

        private void ConfigureProvider()
        {
            Type providerType = Type.GetType(_settings.ProviderClass);
            global::System.Diagnostics.Debug.Assert(providerType != null, "providerType != null");
            var provider = (IActorRefProvider)Activator.CreateInstance(providerType, _name, _settings, _eventStream);
            _provider = provider;
        }
        public Settings(ActorSystem system, Config config)
        {
            _userConfig = config;
            _fallbackConfig = ConfigurationFactory.Default();            
            RebuildConfig();

            System = system;
            
            ConfigVersion = Config.GetString("akka.version");
            ProviderClass = Config.GetString("akka.actor.provider");
            var providerType = Type.GetType(ProviderClass);
            if (providerType == null)
                throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid type name : '{0}'", ProviderClass));
            if (!typeof(IActorRefProvider).IsAssignableFrom(providerType))
                throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid actor ref provider: '{0}'", ProviderClass));
            
            SupervisorStrategyClass = Config.GetString("akka.actor.guardian-supervisor-strategy");

            AskTimeout = Config.GetTimeSpan("akka.actor.ask-timeout", allowInfinite: true);
            CreationTimeout = Config.GetTimeSpan("akka.actor.creation-timeout");
            UnstartedPushTimeout = Config.GetTimeSpan("akka.actor.unstarted-push-timeout");

            SerializeAllMessages = Config.GetBoolean("akka.actor.serialize-messages");
            SerializeAllCreators = Config.GetBoolean("akka.actor.serialize-creators");

            LogLevel = Config.GetString("akka.loglevel");
            StdoutLogLevel = Config.GetString("akka.stdout-loglevel");
            Loggers = Config.GetStringList("akka.loggers");

            LoggerStartTimeout = Config.GetTimeSpan("akka.logger-startup-timeout");

            //handled
            LogConfigOnStart = Config.GetBoolean("akka.log-config-on-start");
            LogDeadLetters = 0;
            switch (Config.GetString("akka.log-dead-letters"))
            {
                case "on":
                case "true":
                    LogDeadLetters = int.MaxValue;
                    break;
                case "off":
                case "false":
                    LogDeadLetters = 0;
                    break;
                default:
                    LogDeadLetters = Config.GetInt("akka.log-dead-letters");
                    break;
            }
            LogDeadLettersDuringShutdown = Config.GetBoolean("akka.log-dead-letters-during-shutdown");
            AddLoggingReceive = Config.GetBoolean("akka.actor.debug.receive");
            DebugAutoReceive = Config.GetBoolean("akka.actor.debug.autoreceive");
            DebugLifecycle = Config.GetBoolean("akka.actor.debug.lifecycle");
            FsmDebugEvent = Config.GetBoolean("akka.actor.debug.fsm");
            DebugEventStream = Config.GetBoolean("akka.actor.debug.event-stream");
            DebugUnhandledMessage = Config.GetBoolean("akka.actor.debug.unhandled");
            DebugRouterMisconfiguration = Config.GetBoolean("akka.actor.debug.router-misconfiguration");
            Home = Config.GetString("akka.home") ?? "";
            DefaultVirtualNodesFactor = Config.GetInt("akka.actor.deployment.default.virtual-nodes-factor");

            SchedulerClass = Config.GetString("akka.scheduler.implementation");
            //TODO: dunno.. we dont have FiniteStateMachines, dont know what the rest is
            /*              
                final val SchedulerClass: String = getString("akka.scheduler.implementation")
                final val Daemonicity: Boolean = getBoolean("akka.daemonic")                
                final val DefaultVirtualNodesFactor: Int = getInt("akka.actor.deployment.default.virtual-nodes-factor")
             */
        }

분명히 프로필의akka를 보십시오.actor.provider:
<configuration>
  <configSections>
    <section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
  </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <akka>
    <hocon>
      <![CDATA[
          akka {  
                actor {
                    provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"
                }
                remote {
                    helios.tcp {
                        transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
                        applied-adapters = []
                        transport-protocol = tcp
                        port = 0
                        hostname = localhost
                    }
                }
            }
      ]]>
    </hocon>
  </akka>
</configuration>

RemoteActorRefProvider:
        public LocalActorRef SystemGuardian { get { return _local.SystemGuardian; } }

        public RemoteActorRefProvider(string systemName, Settings settings, EventStream eventStream)
        {
            settings.InjectTopLevelFallback(RemoteConfigFactory.Default());

            var remoteDeployer = new RemoteDeployer(settings);
            Func<ActorPath, IInternalActorRef> deadLettersFactory = path => new RemoteDeadLetterActorRef(this, path, eventStream);
            _local = new LocalActorRefProvider(systemName, settings, eventStream, remoteDeployer, deadLettersFactory);
            RemoteSettings = new RemoteSettings(settings.Config);
            Deployer = remoteDeployer;
            _log = _local.Log;
        }

알겠습니다. LocalActorRefProvider를 보십시오.
        public void Init(ActorSystemImpl system)
        {
            _system = system;
            //The following are the lazy val statements in Akka
            var defaultDispatcher = system.Dispatchers.DefaultGlobalDispatcher;
            _defaultMailbox = () => new ConcurrentQueueMailbox(); //TODO:system.Mailboxes.FromConfig(Mailboxes.DefaultMailboxId)
            _rootGuardian = CreateRootGuardian(system);
            _tempContainer = new VirtualPathContainer(system.Provider, _tempNode, _rootGuardian, _log);
            _rootGuardian.SetTempContainer(_tempContainer);
            _userGuardian = CreateUserGuardian(_rootGuardian, "user");
            _systemGuardian = CreateSystemGuardian(_rootGuardian, "system", _userGuardian);
            //End of lazy val

            _rootGuardian.Start();
            // chain death watchers so that killing guardian stops the application
            _systemGuardian.Tell(new Watch(_userGuardian, _systemGuardian));    //Should be SendSystemMessage
            _rootGuardian.Tell(new Watch(_systemGuardian, _rootGuardian));      //Should be SendSystemMessage
            _eventStream.StartDefaultLoggers(_system);
        }
        private LocalActorRef CreateUserGuardian(LocalActorRef rootGuardian, string name)   //Corresponds to Akka's: override lazy val guardian: LocalActorRef
        {
            return CreateRootGuardianChild(rootGuardian, name, () =>
            {
                var props = Props.Create<GuardianActor>(UserGuardianSupervisorStrategy);

                var userGuardian = new LocalActorRef(_system, props, DefaultDispatcher, _defaultMailbox, rootGuardian, RootPath/name);
                return userGuardian;
            });         
        }

이 RootPath는 작업자를 다시 로드한 것으로 보입니다.
        public static ActorPath operator /(ActorPath path, string name)
        {
            return new ChildActorPath(path, name, 0);
        }

        public static ActorPath operator /(ActorPath path, IEnumerable<string> name)
        {
            var a = path;
            foreach (string element in name)
            {
                a = a / element;
            }
            return a;
        }

지금userGuardian 경로는 보았습니다.
LocalActorRefProvider:

     public LocalActorRef Guardian { get { return _userGuardian; } }

RemoteActorRefProvider:

     public LocalActorRef Guardian { get { return _local.Guardian; } }

다시 시스템을 보러 오세요.ActorOf("tester"):
        public override IActorRef ActorOf(Props props, string name = null)
        {
            return _provider.Guardian.Cell.ActorOf(props, name: name);
        }

이것은 바로 내가 조립한provider가 초래한 것이다. 사실은 설정 문제이다. 물론 이렇게 보면 우리는 자신의provider를 실현할 수 있다. 하고 싶은 대로 할 수 있다. 시간이 있으면 문서를 보아야 한다. 그러나 생각해 보면 문서는 어떻게 사용하는지, 어떻게 실현하는지 말하지 않을 것이다. 왜, 어떻게 바꾸는지 알고 싶으면 코드를 직접 보아야 한다.

좋은 웹페이지 즐겨찾기