2013-01-14 2 views
3

J'essaie de construire un processus de messagerie entre les acteurs Akka pour représenter le maître donnant un travail au travailleur, et de garder un œil sur elle. Ma question estAkka acteur transfert de travail avec Futures

  1. Est-ce que je propose ci-dessous une approche raisonnable et
  2. même si elle est pas, je voudrais savoir comment cela pourrait se faire correctement avec la composition des contrats à terme, pour la l'amour de mon éducation future.

Le processus que je voudrais quelque chose comme ça va

1) maître envoie travail des travailleurs avec un ask. Il attend une réponse dans les 5 secondes, sinon il considère que le travailleur a perdu sa chance et il devra recommencer à enchérir.

import context.dispatcher 
implicit val timeout = Timeout(5 seconds) 
val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[Future[WorkCompleted]] 

2a) Si le travailleur ne répond pas dans les 5 secondes, je voudrais que le maître lui-même envoyer un message disant à réattribuer le travail.

self ! WorkAllocationFailed(work, worker) 

2b) Si le travailleur ne répond alors il nous donne un avenir [WorkCompleted]. J'aimerais attendre que l'avenir soit terminé pour, disons, 2 minutes.

3a) Si Future [WorkCompleted] ne parvient pas à terminer dans le délai réattribuer alors le travail

self ! WorkFailed(work, worker) 

3b) Si l'avenir [WorkCompleted] réussit recueillir le résultat

I J'ai essayé de créer cette logique, mais je suis dans un pétrin avec onComplete imbriqué, et je ne sais pas comment faire le délai d'attente sur le futur [WorkCompleted]. J'ai essayé de lire le Akka 2.10 Futures docs, mais n'a pas pu trouver une solution.

Répondre

2

Je suis d'accord avec la réponse de Endre - tous très bons points.

Que diriez-vous ceci:

1) Prendre rendez-vous un message pour le délai d'attente (en utilisant system.scheduler.scheduleOnce)

2) Envoyer le message de travail à l'aide d'tell régulière

3a) Si la le travail terminé revient avant le message d'expiration, annule le travail planifié et réaffecte le travail en utilisant les étapes 1 et 2

3b) Si le travail terminé revient après le message d'expiration En soit ignorez-le ou annulez le travail réalloué.

Un avenir à terme peut être utile chez le travailleur, surtout si le travail prend beaucoup de temps ou bloque. Le travailleur peut utiliser un avenir pour faire le travail et rester disponible pour gérer plus de messages entrants, par exemple pour annuler le travail.

2

L'idée générale, que vous avez un maître qui transmet des tâches à un groupe de travailleurs est un modèle sonore. Par contre, je ne recommande pas d'utiliser Futures lorsque toutes les parties de votre système sont déjà des acteurs. Au lieu de soumettre le travail en utilisant ask, vous pouvez simplement l'envoyer via tell. Le maître pourrait alors vérifier périodiquement les travaux expirés et les soumettre à nouveau.

Aussi, appeler onComplete dans le corps de l'acteur est très dangereux, car il s'exécute sur un thread potentiellement différent. Le moyen le plus sûr de communiquer avec les acteurs est de transmettre des messages. Si vous avez un avenir et que vous voulez que quelque chose soit fait dans l'acteur lorsque le futur est terminé, il est préférable d'utiliser le modèle de pipe.

Il existe également un bogue mineur dans votre extrait de code. Si votre acteur de travailleur répond avec WorkCompleted, alors c'est la ligne que vous vouliez vraiment:

val workCompletedFuture = (worker ? WorkTicket(work)).mapTo[WorkCompleted] 
Questions connexes