2013-04-13 15 views
5

Questa è una domanda in due parti, in primo luogo più una domanda di progettazione che come implementarla, e in secondo luogo alcuni problemi di implementazione con Akka.Akka, Scalatra e Web state questions

Sto utilizzando Scalatra per creare un endpoint del servizio REST che quando chiamato estrae le immagini da più fonti, le manipola e le restituisce. Questo è potenzialmente un processo piuttosto lungo e probabilmente sarà più lungo di quanto sia accettabile per un singolo ciclo di richiesta/risposta http.

Il mio pensiero su questo è che quando viene effettuata la chiamata darò il via ad un gruppo di attori Akka per estrarre le risorse dell'immagine, e far loro consegnare il risultato a Attori di elaborazione delle immagini per ridimensionarli ecc. La richiesta iniziale stessa dovrebbe ritornare istantaneamente una sorta di ID di elaborazione che può essere utilizzato per effettuare chiamate di polling successive a un altro endpoint che restituirà i risultati mentre vengono elaborati, con un flag per determinare se sono disponibili più risultati per consentire al client di interrompere il polling.

mie domande, sono i seguenti:

  1. Ha senso da un punto di vista del design?
  2. Se utilizzo questo approccio, ciascuna richiesta successiva per recuperare le immagini elaborate dovrebbe avere una sorta di consapevolezza dello stato per sapere quali immagini il cliente ha già ricevuto. Come gestiresti questo stato?
  3. Non ho mai guardato a questo, ma una richiesta HTTP di stile cometa di lunga durata ha più senso del polling in questa situazione?

Attuazione Parte

Supponendo io finisco con un design simile al precedente, sono molto nuovo a Scalatra & Akka (o qualsiasi paradigma attore) e ho un paio di domande.

Ok, il primo è una domanda specifica Scala/Scalatra I think. Ok, ho guardato la documentazione Scalatra su Akka http://www.scalatra.org/guides/async/akka.html, e in questo esempio si impostare le applicazioni bootstrap come segue:

// 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/*") 
    } 

Si considera che il bootstraping di scalatra accade una volta all'avvio dell'applicazione, così fa system.actorOf (Puntelli [MyActor]) crea una singola istanza o una per richiesta?

In secondo luogo, dire la mia classe MyActor (o un nome più sensibile) ha fatto la seguente:

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 
    } 
} 

Ora, in questo caso, più ci sono più posti sarò Recupero delle immagini e così diversi attori sarà Grabbing questi dati. Quando trovano immagini appropriate, vari attori saranno utilizzati per elaborare le immagini. Se vado con il mio disegno, allora devo segnalare da qualche parte che per un dato ProcessId non ci sono più immagini elaborate disponibili. Ciò significa che ho bisogno di sapere quando TUTTI gli attori di ricerca di immagini e di elaborazione delle immagini hanno finito per un determinato ID di elaborazione. Come faccio a fare questo?

Quindi quella era una domanda, informazioni da consumare, spero che fosse logico.

Cheers. Chris.

risposta

3

Un bel po 'di domande qui.Risposte rapide:

  1. Sì, penso di sì.

  2. Probabilmente si desidera utilizzare una classe di attore come aggregatore, master o coordinatore, che dà il via al recupero delle immagini e alle classi di attore di elaborazione delle immagini. L'aggregatore contiene quindi la logica per quando il calcolo generale può essere considerato completo. Ci sono alcuni esempi di questo genere di cose che galleggiano su Internet, se vuoi che esempi concreti corrispondano a quello che stai facendo, assicurati di guardare gli esempi di Akka 2.1.x, poiché è quello di cui hai probabilmente bisogno se tu? usando l'attuale codice di Scalatra.

  3. Potrebbe essere una buona idea. Scalatra ha un'integrazione con il framework Atmosphere che rende abbastanza facile fare il polling lungo websocket/cometa. È possibile leggere su in the docs. Se abbia senso per la tua applicazione dipende da molti fattori, ma vale la pena guardare. Nella mia esperienza, la programmazione dei socket può a volte essere sorprendente ea volte essere più fastidiosa di quanto valga la pena: se si utilizzano molti proxy, ad esempio, le web socket hanno problemi a meno che SSL non sia in uso. È una cosa bella, però, vedere le informazioni entrare nel client non appena sono disponibili.

Per l'altra domanda, sulla creazione ActorSystem:

In Scalatra, i controller vengono istanziati su una base per-request; ActorSystem nel codice di esempio viene inizializzato solo una volta. Ogni volta che arriva una richiesta, viene creata una nuova istanza del controller, con un riferimento a ActorSystem.

La creazione di ActorSystem è a heavyweight operation e dovrebbe accadere quante volte è possibile farla franca.

+0

Risposta molto completa, grazie. Ora sto pensando che cometa non abbia senso per questo poiché queste richieste verranno da più fonti e non voglio imporle questo su di loro. Segnalo come corretto, ma mi manca il punto su come ActorSystem instanzia gli attori. Questo è dovuto al modo in cui ho posto la mia domanda, che è stupida a rileggere :-). – Owen

+0

Così ho chiesto se system.actorOf (Puntatori [MyActor]) avrebbe instansiato un nuovo MyActor per richiesta, ma ovviamente non lo farà. Ma se non avessi passato il riferimento a MyActor al controller, e solo il riferimento a ActorSystem, chiamerei actorOf per creare una nuova istanza ogni volta? In tal caso, come posso controllare il numero di attori creati? Idealmente, voglio un pool di questi ragazzi disponibili tra cui scegliere. In realtà, a pensarci bene, dovrei leggere di più i documenti e smettere di fare domande :-) – Owen

+0

Immagino di aver suonato un po 'negativo sul frontalino. Tieni presente che Atmosphere ricade nel sondaggio a lungo termine in situazioni in cui i web socket non rimangono stabili, quindi potrebbero comunque valere la pena provare. – futurechimp