2013-04-14 10 views
12

Sono confuso su come assicurarsi che i miei attori abbiano le dipendenze appropriate usando il modello di torta. Mi sto ancora occupando di questo, e non riesco a trovare alcun esempio da nessuna parte. In pratica sto solo cercando un tutorial/risorsa da seguire.Akka e pattern di torta

Cheers, Chris.

risposta

10

Attori come dipendenza:

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) 
    } 
} 

attori aventi dipendenze (dove non c'è nulla speciale ai):

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

Che dire il contrario, non le cose che hanno attori come le dipendenze, ma attori che hanno le dipendenze, che è quello che penso l'OP chiedeva di. –

+0

Thx per averlo indicato. Ho aggiornato la mia risposta. – agilesteel

+1

Ma il mio problema è che quando ServiceActor deve passare un messaggio ad OtherServiceActor, allora il modo standard che ho letto sembra utilizzare il metodo "context.actorOf [OtherServiceActor]" per creare l'attore richiesto. A questo punto, ottengo errori se OtherServiceActor è incluso in un tratto in quanto non è in grado di istanziarlo in tale ambito. – Owen

2

Soltanto Gotcha supplementare, come sottolineato da Owen, è che gli attori con macchine actorOf(Props[MyClass]) non funzionerà per le classi interne. Cioè: il seguente sarà sicuro:

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

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

Secondo la documentazione a http://doc.akka.io/docs/akka/snapshot/scala/actors.html,

se non sono dichiarate all'interno di un oggetto di livello superiore poi allegando esempio di questo riferimento deve essere trasmesso come il primo argomento

Tuttavia, questo non sembra essere supportato dalle firme del metodo Scaladoc Props. L'unico modo che ho trovato è stato usare il costruttore Props (attore: attore), istanziare l'attore mysql e passarlo a Props.

val myActorRef = system.actorOf(Props(new MyActor(arg1, arg2))) 

sarebbe interessata a sapere se c'è un modo migliore ..

+1

È possibile utilizzare actorOf (Puntatori (classOf [SomeActor], someArgument)). –