2017-02-13 1 views
2

J'ai construit un acteur Akka qui interroge une API à intervalles réguliers, comme ceci:Obtenez un message d'un acteur Akka

val cancellable = 
    system.scheduler.schedule(0 milliseconds, 
     5 seconds, 
     actor, 
     QueryController(1)) 

L'acteur, en substance est:

object UpdateStatistics { 
    /** 
    * Query the controller for the given switch Id 
    * 
    * @param dpId Switch's Id 
    */ 
    case class QueryController(dpId: Int) 
    case object Stop 

    def props: Props = Props[UpdateStatistics] 
} 

class UpdateStatistics extends Actor with akka.actor.ActorLogging { 
    import UpdateStatistics._ 

    def receive = { 

    case QueryController(id) => 
     import context.dispatcher 
     log.info(s"Receiving request to query controller") 
     Future { FlowCollector.getSwitchFlows(1) } onComplete { 
     f => self ! f.get 
     } 
    case Stop => 
     log.info(s"Shuting down") 
     context stop self 
    case json: JValue => 
     log.info("Getting json response, computing features...") 
     val features = FeatureExtractor.getFeatures(json) 
     log.debug(s"Features: $features") 
     sender ! features 
    case x => 
     log.warning("Received unknown message: {}", x) 
    } 
} 

Ce que j'essaie de faire est d'obtenir le message json:Jvalue sur UpdateStatistics acteur. La lecture du Akka docs Je pensais que cela peut être utile:

implicit val i = inbox() 
    i.select() { 
    case x => println(s"Valor Devuelto $x") 
    } 
    println(i receive(2.second)) 

Mais je ne sais pas comment modifier UpdateStatistics acteur afin d'envoyer le résultat à la boîte de réception ci-dessus.

Une autre option que j'ai lue dans les documents est event streams.

Mais je ne pense pas que ce soit la bonne façon.

Existe-t-il un moyen de réaliser ce que je veux faire? Ou dois-je utiliser un second Actor auquel j'ai envoyé la réponse JSON?

+0

Qu'est-ce que vous entendez exactement par le fait de sortir le message de l'acteur 'UpdateStatistic'? Qui est le destinataire? Que voulez-vous faire avec les données? –

+1

@JorgenGValley Je veux dire envoyer le message au fil principal, en dehors d'Akka. Par exemple, dans l'application principale, je lance un système d'acteur et planifie l'acteur pour interroger une API. Je veux la réponse de l'acteur dans l'application principale, pas dans Akka. Je ne sais pas si j'ai expliqué correctement. – elbaulp

Répondre

4

Vous recherchez probablement le modèle ask dans AKKA. Cela vous permettra de renvoyer une valeur à l'expéditeur.

import akka.pattern.ask 
import akka.util.duration._ 

implicit val timeout = Timeout(5 seconds) 

val future = actor ? QueryController(1)  
val result = Await.result(future, timeout.duration).asInstanceOf[JValue] 

println(result) 

Pour faire ce travail, vous devez envoyer la réponse à la sender d'origine, plutôt que self. En outre, vous devriez prendre garde aux dangers de la fermeture sur sender dans un avenir lors de la manipulation des messages.

+0

Mais cela bloquerait le fil, non? 'UpdateStatistics' va publier des messages toutes les 5 secondes, avec votre solution, je ne peux obtenir la première réponse de' UpdateStatistics' Ai-je raison? Merci pour votre réponse. – elbaulp

+1

Comme écrit, il bloquerait. Au lieu de cela, utilisez simplement 'future.onSuccess' pour gérer le résultat –