2012-02-01 1 views
0

Si je comprends bien, un acteur peut être envoyé un message "fire and forget" style avec le! opérateur, ou "Send-And-Receive-Future" style avec le? opérateur. Un acteur qui passe un message via? doit appeler un self.reply ou l'expéditeur recevra une exception de timeout. D'un autre côté, un acteur qui passe un message via! ne peut pas avoir d'auto-réponse si le message n'est pas transmis par un autre acteur.Un acteur Akka doit-il distinguer si, lorsqu'un message est passé, un futur renvoyé est attendu?

Ma question est, l'acteur est censé savoir au moment de la compilation s'il sera invoqué avec! ou ? ??? Ou si la nécessité d'auto-réponse peut être déterminée à l'exécution, comment cela peut-il être déterminé? Peut-être self.tryReply est impliqué, mais la documentation akka semble impliquer qu'une tentative ratée de réponse est un cas d'erreur, alors que si l'expéditeur n'est pas un acteur, ce n'est pas vraiment une erreur de ne pas répondre si le message est passé avec !

Edit:

Voici quelques code:

package akTest 

import akka.actor.Actor 

object Main1 { 
    val worker = Actor.actorOf[ak].start() 

    def main(args: Array[String]) { 
    val resp = worker ? "Hi" 
    resp.get 
    println(resp) 
    } 
} 

class ak extends Actor { 
    def receive = { 
    case msg:String => { 
     val response = "Received: " + msg 
     println(response) 
     response 
    } 
    } 
} 

Cela devient Exception in thread "main" akka.dispatch.FutureTimeoutException: Futures timed out after [4995] milliseconds

J'ajouter un self.reply à l'acteur:

class ak extends Actor { 
    def receive = { 
    case msg:String => { 
     val response = "Received: " + msg 
     println(response) 
     self.reply(response) 
     response 
    } 
    } 
} 

Ce changement fixe l'erreur de dépassement de délai. Mais maintenant, si j'ai un Main2 qui envoie un feu et d'oublier un message:

object Main2 { 
    val worker = Actor.actorOf[ak].start() 

    def main(args: Array[String]) { 
    val resp = worker ! "Hi" 
    println(resp) 
    } 
} 

, une nouvelle erreur se produit: [ERROR] [2/1/12 2:04 PM] [akka:event-driven:dispatcher:global-1] [LocalActorRef] No sender in scope, can't reply.

Comment puis-je écrire mon acteur pour éliminer le couplage entre sa manière de réponse et la méthode d'invocation de l'expéditeur? Je ne veux pas avoir 1 version de l'acteur pour! et une deuxième version de l'acteur pour?

Répondre

2

si senderFuture.isDefined vous un avenir pour répondre à

+2

Je lis toutes ces questions et Akka ils ont tous une chose en commun: presque aucun d'entre eux démontrent la solution. C'est un peu le but de cet endroit. [BTW, clairement les documents et les exemples ne sont pas assez claires.] – Rob

+1

Si vous voulez améliorer la documentation, vous devez signaler ce qui doit être fixé sur le ML ou ouvrir un ticket directement car ce sont nos canaux de rétroaction. Je n'invoque pas de code sur SO car tout d'abord, je n'ai pas le temps de le faire, et d'autre part, parce qu'il n'est pas compilé, et peut donc devenir facilement obsolète. –

+0

Euh, j'ai donné un exemple parfait dans mon article il y a une semaine Viktor: tous les exemples dans les docs qui utilisent Actors ont juste un tas de choses en parallèle, puis un auditeur crache un message sur la console et mettre fin. Complètement inutile. Voici ce qui serait utile: montrez-moi comment vous pouvez envoyer un message à un acteur, faites-le passer à d'autres acteurs, puis renvoyez le résultat au service REST afin qu'il puisse le renvoyer. Regardez la documentation de Spray si vous avez besoin d'aide supplémentaire: leur première page montre exactement comment cela est fait. Votre documentation, d'autre part ... – Rob

Questions connexes