Akka和蛋糕模式

12

我不知道如何使用蛋糕模式确保我的演员有适当的依赖关系。 我还在逐渐掌握这个过程,但我无法找到任何示例。我基本上只是在寻找教程/资源来学习。

谢谢,克里斯。

2个回答

10

演员作为依赖关系:

trait DBComponent {
   def db: ActorRef // no compile time guarantees

   type K
   type V

   object DBActor {
      case class Put(key: K, value: V)
      case class Get(key: K)
   }

   class DBActor {
      import DBActor._
      val db = scala.collection.mutable.Map.empty[K, V]
      def receive = {
         case Put(k, v) => db.put(k, v)
         case Get(k) => sender ! db.get(k)
      }
   }
}

trait ServiceComponent {
   this: DBComponent =>

   import DBActor._

   // you could be talking to deadLetters for all you know
   def put(k: K, v: V): Unit = db ! Put(k, v)
   def get(k: K): Option[V] = {
      implicit val timeout = Timeout(5 seconds)
      val future = ask(actor, Get(k)).mapTo[Option[V]]
      Await.result(future, timeout.duration)
   }
}

有依赖关系的演员(其中没有什么特别之处):

trait DBComponent {
   def db: DB

   type K
   type V

   trait DB {
      def put(key: K, value: V): Unit
      def get(key: K): Option[V]
   }
}

trait ServiceComponent {
   this: DBComponent =>

   object ServiceActor {
      case class Put(key: K, value: V)
      case class Get(key: K)
   }

   class ServiceActor {
      import ServiceActor._
      def receive = {
         case Put(k, v) => db.put(k, v) // db is in scope
         case Get(k) => sender ! db.get(k)
      }
   }
}

1
另一方面呢?不是事物具有依赖性,而是演员具有依赖性,这就是我认为 OP 所问的问题。 - Viktor Klang
1
但我的问题是,当ServiceActor需要向OtherServiceActor传递消息时,我所阅读的标准方法似乎是使用"context.actorOf [OtherServiceActor]"方法来创建所需的actor。在这一点上,如果OtherServiceActor被包装在trait中,则会出现错误,因为它无法在该范围内实例化。 - Owen
好的,我开始打了一个漫长的编辑,但在一半的时候意识到了自己问题的答案。 - Owen
在一个特质中定义的Actor类是否可行?据我所知,Akka actors不能是非静态内部类,否则将会出现“akka.actor.ActorInitializationException:exception during creation”的错误。 - Cristian Vrabie
好的,我刚试了一下,如果使用system.actorOf(Props[ServiceActor])实例化,它会抛出异常,但是如果使用system.actorOf(Props(new ServiceActor))就可以正常工作。 - Cristian Vrabie

2

还有一个需要注意的问题,正如Owen所指出的那样,使用actorOf(Props[MyClass])创建Actor对于内部类是行不通的。也就是说,以下代码会失败:

trait MyComponent {
  class MyActor {
    def receive = ...
  }
}

new MyComponent {
  val myActorRef = system.actorOf( Props[MyActor] )
}

根据http://doc.akka.io/docs/akka/snapshot/scala/actors.html文档,如果Actor不在顶层对象中声明,则需要将封闭实例的“this”引用作为第一个参数传递。然而,这似乎不受scaladoc Props方法签名的支持。我发现唯一的解决方法是使用Props(actor:Actor)构造函数,实例化mysql Actor并将其传递给Props。
val myActorRef = system.actorOf( Props( new MyActor(arg1, arg2) ) )

想知道是否有更好的方法...


1
你可以使用actorOf(Props(classOf[SomeActor], someArgument))。 - James Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接