12
votes

Interagir avec acteur AKKA en dehors des acteurs

Je veux interagir avec des acteurs Akka de mon propre fil. Actuellement, j'aime bien: XXX

Mais je ne suis pas sûr comment cela interagit réellement avec mon fil? Je souhaite que la réception soit asynchrone, c'est-à-dire que je veux raccrocher le fil pendant la réception pour permettre à d'autres travaux. Je viens de lire récemment sur le système d'Akka Box. Boîte de réception AKKA API

Je pense que je me souviens qu'attendre crée un nouvel acteur à chaque fois. Quelles sont les différences entre Await + Demander et Boîte de réception et que quelqu'un peut-il me donner un exemple de la manière de créer une boîte de réception et de l'utiliser pour communiquer avec des acteurs de "l'extérieur"?

edit Juste pour clarifier, je ne veux pas le même thread pour continuer à travailler, je veux que cela arrête de charger un processeur de processeur et de laisser d'autres threads à travailler jusqu'à ce qu'il reçoive quelque chose, puis réveille-toi. < / p>


11 commentaires

Dans Akka, vous devriez mieux utiliser MapTo [Type] au lieu de asinstance de


Quel est l'avantage? :)


asinstance de jette une exception, quand il échoue. MapTo retourne un avenir échoué.


La chose dangereuse est que asinstance de pourrait réellement réussir et échouer plus tard, lorsqu'une méthode spécifique est appelée.


Attend également ne pas créer de nouveaux acteurs, il est seul but de bloquer l'exécution jusqu'à attendre pour le résultat. Le seul moyen de créer un acteur passe par system.actorof (...)


Est-ce que ça a porté le fil cependant?


Oui, vous pouvez lire sur l'utilisation d'Akka et de Futures ici


Il existe un exemple dans le Documentation < / a>.


@Alexiv: System.Actorof (...) n'est pas le seul moyen de créer un acteur. Demandez ou ? crée un nouvel acteur, actordsl.inbox crée un nouvel acteur.


@senia Désolé n'a jamais utilisé le DSL d'Akka, mais comme je peux comprendre de Cette ligne Cela ne crée pas un nouvel acteur, mais retourne un avenir avec une référence d'acteur


@senia Il renvoie un nouvel acteur avec mécanisme acteur, mais pas un nouvel acteur


3 Réponses :


9
votes

Comme écrit dans la documentation future de l'AKKA, à l'aide d'attendu Bloque le thread actuel jusqu'à attendre pour le résultat.

Exemple P>

import scala.concurrent.Await
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._

implicit val timeout = Timeout(5 seconds)
val future = actor ? msg // enabled by the “ask” import
val result = Await.result(future, timeout.duration).asInstanceOf[String]


6 commentaires

Pouvez-vous élaborer la différence entre cela et l'utilisation de la boîte de réception?


@Felix Désolé n'a jamais utilisé le DSL d'Akka, mais comme je peux voir que l'utilisation principale de la boîte de réception est que la demande ne peut pas 1) recevoir plusieurs réponses et 2) regarder le cycle de vie d'autres acteurs. La boîte de réception


@senia n'est toujours pas d'accord avec vous, demandez à retourner un avenir avec Actorref à travers une activité active, mais cela ne crée pas un nouvel acteur


@AlexLV, si vous utilisez une question à l'extérieur d'un acteur, un acteur temporaire est créé sous la hotte. En effet, afin de répondre, vous avez besoin d'un acteur Ref pour renvoyer à VIA! opérateur. L'acteur est de courte durée et est arrêté après la réception de la réponse ou d'un délai d'attente.


Comment pourrais-je utiliser cela avec un radioducteur qui devrait répondre à plusieurs reprises pour chaque avenir? Merci.


Pas besoin de bloquer. Comme mentionné dans les documents, vous pouvez importer scala.concurrent.future et akka.pattern.ask, puis Val Future: futur [string] = Demandez (acteur, msg) .Mapto [string]



0
votes

Si vous ne voulez pas bloquer sur le côté appelant, n'utilisez pas d'attendre, utilisez les rappels non bloquants, comme l'onctuation, l'onduleur et l'ONCOMPLETE. Lorsque vous faites cela, une tâche future est mise dans tout ce que l'exécutionContext est de la portée au moment de la demande (?). Lorsqu'une réponse est reçue, ce rappel est invoqué de manière asynchrone via l'exécutionContext. De cette façon, vous évitez de bloquer tous ensemble dans le fil qui apporte la demande à l'acteur, puis le rappel est traité dans la piscine de thread liée à l'exécutionContext.

En outre, je crois que la boîte de réception que vous mentionnez est destinée à tester des trucs de l'acteur dans la RÉPL (au moins c'est ce que les Docs sur Actordsl) ont. Coller avec l'approche que vous avez d'utiliser demande de l'extérieur de l'acteur. Laissez AKKA créer l'acteur de courte durée qu'elle a besoin pour la communication sous le capot pour les appels d'acteur non acteur. Ensuite, passez à un rappel non bloquant comme je l'ai suggéré ci-dessus. Je crois que c'est ce que vous recherchez.


0 commentaires

5
votes

Le attendre.receive code> fait partie de l'API Scala Concurrency et n'a rien à voir avec les acteurs. Son but est le blocage du fil actuel jusqu'à ce que le futur fourni ou la limite de délai d'attente commence et tout se termine dans une exception de délai d'attente.

L'opérateur de demande ? Code> créera en effet un acteur temporaire Dans le seul but de l'attendre pour la réponse de l'acteur pointé par la variable code> Code> et complétant l'avenir que vous avez obtenu lorsque vous avez appelé l'opérateur d'achat avec la réponse reçue. P>

Votre code bloque essentiellement l'ensemble du fil. Comme il a été indiqué, si vous voulez libérer le fil actuel et continuer à faire un autre travail, vous pouvez attacher un rappel à l'avenir. P>

import akka.actor.ActorDSL._
implicit val actorSystem: ActorSystem = // provide an actor system here or any actor ref factory

actor(new Act {
  aref ! GroupReceive(fromRank)
  context.setReceiveTimeout(timeout) //optional
  become {
    case ReceiveTimeout => {
      //handle the timeout
      context.stop(self)
    }
    case res => {
      //do your thing with res, asynchronously
      context.stop(self)
    }
  }
}

//some other code which won't wait for the above operations


1 commentaires

En ce qui concerne l'exemple de DSL, une partie de votre réponse: Bien que cela fonctionne pour des demandes de latence plus élevées, pour une demande / réponse très rapide, elle peut échouer car deviendra-t-il un peu de temps à lancer. Une action DSL devrait être initialisée exactement comme dans cette question pour toujours fonctionner: Stackoverflow.com/questions/17851849 / ... .