zoukankan      html  css  js  c++  java
  • "Principles of Reactive Programming" 之<Actors are Distributed> (2)

    Actor Path

    我们知道actor是有层级的(hierarchical),第、每个actor在它的父actor的名字空间下都有一个名字。这样就构成了一个树状的结构,就像是文件系统。每个actor就像文件系统里的一个文件夹,因为每个actor都可以有子actor,因此,它们更像是文件夹,而不是文件。

    val system = ActorSystem("HelloWorld")
    val ref = system.actorOf(Props[Greeter], "greeter")
    println(ref.path)
    // prints: akka://HelloWorld/user/greeter
    

    在这上面这段代码里,greeter的父actor是user(所有用户通过system.actorOf建的actor,都是user的子actor)。

    greeter的path是akka://HelloWorld/user/greeter

    这是一个URI。

    其中authority part是akka://HelloWorld,这也是HelloWorld这个actor system的地址。akka://是一个协议,说明这是一个本地的actor path.

    /user/greeter,是actor的path,这里就是greeter这个actor的path.

    它们加起来就表示greeter这个actor的URI。

    其实,每个actor system可以有多个地址,比如上边的HelloWorld当远程访问时,它的地址可以是 akka.tcp://HelloWorld@10.2.4.6:6565。其中akka.tcp说明这个这个actor system需要通过tcp协议访问,名字是HelloWorld, IP为10.2.4.6,端口为6565。如果访问这个actor system里的greeter这个actor,那么地址是akka.tcp://HelloWorld@10.2.4.6:6565/user/greeter

    这说明每个actor system都可以多个地址,如果它能通过多个协议或者多个IP地址访问。

    The difference between ActorPath and ActorRef

    ActorPath和文件路径一样,你可以随便拼凑文件路径,即使它所指向的地方并没有文件。但是ActorRef一定指向一个存在的文件(对于actor,更像是文件夹,因为actor可以有子actor)。

    每个ActorRef都会有一个path, 指向这个ActorRef。但是ActorPath可以指向一个并不存在的ActorRef,因此ActorPath是不可以被watch的,但是ActorRef可以。因为,ActorRef只能被以有限的方式获取,这些获取方式保证了它一定是某个已经在工作的actor的reference。无法获取一个并不存在的actor的ActorRef。 也因为如此,向一个ActorPath发送消息和向ActorRef发送消息是不同的。

    另外,对于ActorRef,如果一个ActorPath指向的actor停止了,那么它的parent可以用同样的名字启动另一个actor,那么新的actor和已经终止的actor有同样的actorPath,但是它们有不同的ActorRef。ActorRef的最后有一个UID,它标识了ActorRef的不同。

    Actor names are unique within a parent, but can be reused.

    • ActorPath is the full name, whether the actor exists or not.
    • ActorRef points to an actor which was started; an incarnation.

    ActorPath can only optimistically send a message.

    ActorRef can be watched.

    ActorRef example: akka://HelloWorld/user/greeter#43438347   (print 一个ActorRef显示的值)

    Resolving an ActorPath

    case class Resolve(path: ActorPath)
    case class Resolved(path: ActorPath, ref: ActorRef)
    case class NotResoved(path: ActorPath)
    case class ToBeResolved(path: ActorPath, client: ActorRef)
    
    class Resolver extends Actor{
      def receive = {
        case Resolve(path) => context.actorSelection(path) ! Identify(ToBeResolved(path, sender()))
        case ActorIdentity(ToBeResolved(path, client), Some(actorRef)) => client ! Resolved(path, actorRef)
        case ActorIdentity(ToBeResolved(path, client), None) => client ! NotResoved(path)
      }
    }
    

      有些时候我们不能直接获取ActorRef,比如另一个ActorSystem里,不是你创建的一个actor。这时候就需要另一套机制了,就是Identify和ActorIdentify。每一个Actor都能处理Identify消息,把自己的ActorRef封装于ActorIdentify中返回给sender。这就是通过通信来获取ActorRef, 总之, ActorRef是不能凭空先出来一个的,它一定代表一个存在的actor。

    Relative Actor Paths

    Looking up a grand-child:

    •  context.actorSelection("child/grandchild")

    Looking up a sibling:

    • context.actorSelection("../sibling")

    Looking up from the local root:

    • context.actorSelection("/user/app")

    Broadcasting using wildcasts:

    • context.actorSelection("/user/controllers/*")

    actor path的语义跟文件系统的path非常类似。

  • 相关阅读:
    pytorch 文本输入处理
    理解 on-policy 和 off-policy
    Monte Carlo与TD算法
    Monte Calro Tree Search (MCTS)
    强化学习概览
    linux 服务器 keras 深度学习环境搭建
    sed和awk学习整理
    linux shell编程进阶学习(转)
    gdb调试:
    MySQL C API 访问 MySQL 示例
  • 原文地址:https://www.cnblogs.com/devos/p/4172637.html
Copyright © 2011-2022 走看看