15 votes

Séquence de livraison des messages dans les acteurs akka

Je suis assez novice en matière d'Akka et je n'ai pas trouvé la réponse dans le manuel de référence.

Supposons que nous ayons des acteurs distants répartis dans un cluster de 3 machines (A, B, C), où un acteur vit sur chaque machine et les autres ont un actorRef vers 2 autres, c'est-à-dire :

Machine A:
A (real actor)
-> B (ref)
-> C (ref)

Machine B:
-> A (ref)
B (real actor)
-> C (ref)

Machine C:
-> A (ref)
-> B (ref)
C (real actor)

L'acteur A exécute le code suivant :

bRef ! msg1
bRef ! msg2

L'acteur B exécute le code suivant dans le gestionnaire de messages :

case msg1 => 
    cRef ! msg3
    aRef ! msg4

L'acteur C exécute le code suivant dans le gestionnaire de messages :

case msg3 => 
    aRef ! msg5

Puis-je émettre les hypothèses suivantes (le cas échéant) ?

  1. l'acteur B reçoit le message 1 avant de recevoir le message 2

  2. l'acteur A reçoit msg5 avant de recevoir msg4

Et la question complémentaire qui permet probablement de comprendre ce qui précède : Le message envoyé par l'opérateur ! via le réseau est-il vraiment asynchrone ou attend-il que la boîte aux lettres réceptrice le reçoive ? En d'autres termes, la ligne

bRef ! msg1

bloque jusqu'à ce que l'acteur B reçoive le message dans sa boîte aux lettres ou lance-t-il le thread qui s'occupe de l'envoi et poursuit-il l'exécution ?

bRef ! msg2

avant même de savoir que l'acteur B a reçu le message 1 ?

9voto

David McLaughlin Points 3447

Pour (1), vous avez la garantie que msg1 sera mis en file d'attente par le répartiteur avant msg2. Ce qui se passe réellement une fois qu'ils sont mis en file d'attente dépend vraiment du répartiteur que vous utilisez : http://akka.io/docs/akka/1.1.2/scala/dispatchers.html Mais dans votre cas, tant que B peut accepter les deux messages, il recevra toujours le msg1 avant le msg2.

Pour (2), non, vous n'avez pas cette garantie. La méthode ! revient dès que le dispatcher met le message en file d'attente et non pas lorsque le message est accepté par la boîte aux lettres de l'acteur cible. L'envoi est alors effectué dans un autre thread et est sujet à toutes sortes de conditions de course.

Le message envoyé par l'opérateur ! via le réseau est-il réellement asynchrone ou attend-il que la boîte aux lettres réceptrice le reçoive ?

Vous pouvez utiliser une BoundedMailbox avec des acteurs locaux pour montrer que la mise en file d'attente des messages vers les dispatchers est asynchrone avec !

class TestActor extends Actor {
  val mailboxCapacity = BoundedMailbox(capacity = 1)
  self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("test", 1, mailboxCapacity).build

  def receive = {
    case x: String => 
      Thread.sleep(1000)
      println("Received message")
    case _ => 
  }
}

val t = Actor.actorOf[TestActor]
t.start()

t ! "one"; t ! "two"; t ! "three"; println("Main thread");

Impressions :

scala>     t ! "one"; t ! "two"; t ! "three"; println("Main thread");
Received message
Main thread

scala> Received message
Received message

Cela signifie que l'exécution du code dans le fil principal se poursuit avant même de savoir si le message sera délivré ou non. Dans ce cas, l'envoi du message aurait pu être interrompu si nous avions défini un pushTimeout sur le dispatcher et fait attendre Thread.sleep plus longtemps que le timeout.

Comparez cela à l'utilisation de ! !!

scala>     t !! "one"; t !! "two"; t !! "three"; println("test");
Received message
Received message
Received message
test

C'est donc dans cette optique que nous avons décidé d'agir. La façon d'atteindre l'objectif (2) serait la suivante :

case msg1 =>
  cRef !! msg3
  aRef ! msg4

0voto

Daniel C. Sobral Points 159554

Erlang vous offre la première garantie, mais pas la seconde. Akka pourrait également vous donner la première garantie, mais certainement pas la seconde.

Je ne connais pas la réponse à votre question complémentaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X