Je veux interagir avec des acteurs Akka de mon propre fil. Actuellement, j'aime bien: 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 P> 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"? P> edit fort>
Juste pour clarifier, je ne veux pas le même thread Strong> 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> p>
3 Réponses :
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]
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] code>
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. p>
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. p>
Le L'opérateur de demande 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> 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.
? 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>
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
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 / ... .
Dans Akka, vous devriez mieux utiliser
MapTo [Type] code> au lieu de
asinstance de code>
Quel est l'avantage? :)
asinstance de code> jette une exception, quand il échoue.
MapTo CODE> retourne un avenir échoué.
La chose dangereuse est que
asinstance de code> 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 (...) code>
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 (...) code> n'est pas le seul moyen de créer un acteur.
Demandez code> ou
? code> crée un nouvel acteur,
actordsl.inbox code> 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