2013-04-13 2 views
5

Il s'agit d'une question en deux parties, d'abord plus d'une question de conception que la façon de l'implémenter, et deuxièmement des problèmes de mise en œuvre avec Akka. J'utilise Scalatra pour créer un point de fin de service REST qui, lorsqu'il est appelé, extrait des images de plusieurs sources, les manipule et les renvoie. Il s'agit d'un processus potentiellement assez long et qui sera probablement plus long que le cycle de requête/réponse http. Mes réflexions à ce sujet sont que lorsque l'appel est fait, je vais lancer un groupe d'acteurs Akkka pour tirer les ressources de l'image, et leur donner le résultat aux acteurs de traitement d'image à l'échelle, etc. La demande initiale elle-même retournerait instantanément un type d'ID de traitement pouvant être utilisé pour effectuer des appels d'interrogation ultérieurs vers un autre point de terminaison renvoyant les résultats lors du traitement, avec un indicateur pour déterminer s'il existe plus de résultats disponibles pour informer le client qu'il doit arrêter l'interrogation.Akka, Scalatra et Web questions d'état

Mes questions sont les suivantes:

  1. Est-ce logique d'un point de vue de la conception?
  2. Si j'utilise cette approche, chaque requête ultérieure pour récupérer les images traitées devra avoir une sorte de conscience d'état pour savoir quelles images le client a déjà reçues. Comment géreriez-vous cet état?
  3. Je n'ai jamais regardé cela, mais est-ce qu'une requête HTTP de style comète de longue durée aurait plus de sens que d'interroger dans cette situation?

Partie de mise en œuvre

En supposant que je finis avec une conception similaire ci-dessus, je suis très nouveau pour Scalatra & Akka (ou tout autre paradigme Acteur) et j'ai quelques questions. Ok, la première est une question spécifique Scala/Scalatra I pense. Ok, je regardais les Scalatra docs sur Akka http://www.scalatra.org/guides/async/akka.html, et dans cet exemple, ils configurer les applications comme suit amorcer sur:

// Get a handle to an ActorSystem and a reference to one of your actors 
    val system = ActorSystem() 
    val myActor = system.actorOf(Props[MyActor]) 

    // In the init method, mount your servlets with references to the system 
    // and/or ActorRefs, as necessary. 
    override def init(context: ServletContext) { 
    context.mount(new PageRetriever(system), "/*") 
    context.mount(new MyActorApp(system, myActor), "/actors/*") 
    } 

Je suppose que le bootstraping de scalatra se produit une fois au démarrage de l'application, donc ne system.actorOf (Props [MyActor]) crée une instance unique ou une instance par requête?

Deuxièmement, dire que ma classe MyActor (ou un nom plus sensible) fait ce qui suit:

class MyActor extends Actor { 
    def receive = { 
    //Find the [ImageSearchingActor] actor in akka registry and send search message 
    case initiateSearchRequest: InitiateSearchRequestMessage => TODO 

    //Find free [ImageProcessingActors] in akka registry and send each Image url to process 
    case imageInformationFound : ImageInformationFoundMessage => TODO 

    //Persist the result to a cache, or data store with the ProcessingId that all message will pass 
    case imageProcessed : ImageProcessedMessage => TODO 
    } 
} 

Maintenant, dans ce multiple cas, il y a plusieurs endroits où je vais récupérer les images et ainsi de plusieurs acteurs seront l'accaparement des ces données. Quand ils trouveront des images appropriées, plusieurs acteurs seront utilisés pour traiter les images. Si je vais avec mon design, je dois signaler quelque part que pour un ProcessingId donné, il n'y a plus d'images traitées disponibles. Cela signifie que j'ai besoin de savoir quand TOUS les acteurs de la recherche d'image et du traitement d'image ont fini pour un ProcessingId donné. Comment puis-je faire cela?

Donc, c'était beaucoup de question, d'info à consommer, j'espère que c'était logique.

Vive. Chris.

Répondre

3

Voici quelques questions ici.Réponses rapides:

  1. Oui, je pense.

  2. Vous souhaitez probablement utiliser une classe Actor en tant qu'agrégateur, maître ou coordinateur, qui lance les classes d'extraction d'image et de traitement d'image Actor. L'agrégateur contient alors la logique pour quand votre calcul global peut être considéré comme complet. Il y a quelques exemples de ce genre de choses flottant sur Internet, si vous voulez des exemples concrets pour correspondre à ce que vous faites, assurez-vous que vous regardez les exemples Akka 2.1.x, car c'est ce dont vous avez probablement besoin si vous ' re en utilisant la base de code Scalatra actuelle.

  3. Ce pourrait être une bonne idée. Scalatra a une intégration avec le framework Atmosphere, ce qui le rend très facile à faire avec un websocket/comet long polling. Vous pouvez lire environ in the docs. Si cela a du sens pour votre application dépend de beaucoup de facteurs, mais cela vaut la peine d'être regardé. D'après mon expérience, la programmation des sockets peut parfois être incroyable et parfois être plus compliquée que cela en vaut la peine. Par exemple, si vous passez par un grand nombre de proxies, les Websockets ont des problèmes à moins que SSL ne soit utilisé. C'est une belle chose, cependant, de voir l'information poussée dans le client dès qu'elle est disponible.

à l'autre question, sur la création ActorSystem:

En Scalatra, vos contrôleurs sont instanciés sur une base par demande; ActorSystem dans votre exemple de code est initialisé une seule fois. Chaque fois qu'une demande arrive dans la porte, une nouvelle instance de contrôleur est créée, avec une référence à ActorSystem.

La création d'ActorSystem est a heavyweight operation, et devrait se produire aussi peu de fois que vous pouvez vous en sortir.

+0

Réponse très complète, merci. Je pense maintenant que la comète n'a pas de sens pour cela car ces requêtes proviendront de plusieurs sources et je ne veux pas leur imposer cela. Je vais marquer cela comme correct, mais il me manque le point sur la façon dont ActorSystem instancie les acteurs. Cela est dû à la façon dont j'ai posé ma question, ce qui est stupide lors de la relecture :-). – Owen

+0

J'ai donc demandé si system.actorOf (Props [MyActor]) instançait un nouveau MyActor par requête, mais évidemment il ne le sera pas. Mais si je ne passais pas la référence à MyActor au contrôleur, et juste l'arbitre de l'ActorSystem, appelait actorOf créer une nouvelle instance à chaque fois? Si oui, comment contrôler le nombre d'acteurs créés? Idéalement, je veux un groupe de ces types disponibles à choisir. En fait, à la seconde réflexion, je devrais lire les docs un peu plus et arrêter de poser des questions :-) – Owen

+0

Je suppose que j'avais l'air un peu négatif sur le front de socket. Gardez à l'esprit qu'Atlosphere se rabat sur des sondages à long terme dans des situations où les rotules Web ne resteront pas stables, alors elles peuvent toujours valoir la peine d'être essayées. – futurechimp