Я смущен, как обеспечить, чтобы у моих Актеров были соответствующие зависимости, используя шаблон торта. Я все еще с этим справляюсь, и я нигде не могу найти примеров. Я в основном просто ищу учебник/ресурс для подражания.
Привет, Крис.
Я смущен, как обеспечить, чтобы у моих Актеров были соответствующие зависимости, используя шаблон торта. Я все еще с этим справляюсь, и я нигде не могу найти примеров. Я в основном просто ищу учебник/ресурс для подражания.
Привет, Крис.
Актеры как зависимость:
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)
}
}
}
Еще одна дополнительная информация, о которой указывает Оуэн, заключается в том, что создание участников с использованием actorOf(Props[MyClass])
не будет работать для внутренних классов. Т.е.: не будет выполнено следующее:
trait MyComponent {
class MyActor {
def receive = ...
}
}
new MyComponent {
val myActorRef = system.actorOf( Props[MyActor] )
}
Согласно документации на http://doc.akka.io/docs/akka/snapshot/scala/actors.html,
если они не объявлены в объекте верхнего уровня, тогда экземпляров эта ссылка должна быть передана в качестве первого аргумента
Однако это, похоже, не поддерживается сигнатурами метода ретрансляции scaladoc. Единственным способом, который я нашел, было использование конструктора Props (actor: Actor), создающего экземпляр mysql и передачу его в реквизит.
val myActorRef = system.actorOf( Props( new MyActor(arg1, arg2) ) )
Было бы интересно узнать, есть ли лучший способ.