Domanda

Recentemente sono stato il passaggio da attori Scala Akka attori, ma notato che Akka attori usano ActorRef invece dell'oggetto esempio:

val actorRef: ActorRef = Actor.actorOf(new MyActor)

Così ho provato:

val myActor = new MyActor
val actorRef: ActorRef = Actor.actorOf(x)

... di avere sia: 1) ActorRef per inviare messaggi e 2) MyActor ai metodi call su
. Ma ho ottenuto:

akka.actor.ActorInitializationException: ActorRef for instance of actor [MyActor] is not in scope.

Quindi la mia domanda è: Come posso ottenere un'istanza (di un certo tipo) su cui posso chiamare ActorRef simili metodi come ! e anche metodi dall'istanza MyActor

È stato utile?

Soluzione

Quello che stai facendo è un terribile idea. Quindi, semplicemente smettere proprio adesso, passo dalla tastiera, e andare a l'Akka Documentazione e leggere su attori.

Considerate questo:

class YourActor extends Actor {
  var mutableStuff = ...
  def receive = {
    case _ =>
      // mess with mutableStuff
  }
  def publicMethod = // mess with mutableStuff
}

Ora, impostare il sistema e iniziare a inviare messaggi e chiamare quel metodo da altri thread. Boom!

Si sta facendo appunto che cosa Akka e il modello attore aiutare a prevenire. Si sta effettivamente facendo in quattro per rompere quello che hanno già fissato :) Loro non ti consente di farlo.

Ora, è possibile test di unità accedendo direttamente i metodi ma è necessario un TestActorRef per questo. Mentre si sta leggendo la documentazione, leggere la sezione Testing.

Altri suggerimenti

Il meglio che posso in mente è il seguente, piuttosto sporco:
C'è un modo migliore?

import akka.actor._

trait ActorCom {
  var actorRefForInitialization: ActorRef = _
  lazy val actorRef: ActorRef = actorRefForInitialization
  def ?(message: Any)(implicit channel: UntypedChannel = NullChannel, timeout: Actor.Timeout = Actor.defaultTimeout) = actorRef ? message
  def !(msg: Any)(implicit sender: UntypedChannel) = actorRef ! msg
  def start = actorRef.start
}

object AkkaActorFactory {
  def apply[A <: Actor](newInstance: => A with ActorCom): A with ActorCom = {
    var instance: Option[A with ActorCom] = None
    val actorRef = Actor.actorOf({
      instance = Some(newInstance)
      instance.get
    })
    instance.get.actorRefForInitialization = actorRef
    instance.get.actorRef // touch lazy val in ActorCom, to make it equal to actorRef and then its fixed (immutable)
    instance.get
  }
}

class MyActor extends Actor {
  def receive = {
    case "test1" => println("good")
    case "test2" => println("fine")
    case _       => println("bad")
  }
  def sendTestMsg2Myself = self ! "test2"
}

val myActor = AkkaActorFactory(newInstance = new MyActor with ActorCom)
myActor.start
myActor ! "test1"
myActor.sendTestMsg2Myself // example for calling methods on MyActor-instance
myActor ! PoisonPill
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top