2015-11-13 11 views
5

Ultimamente ho studiato il fantastico framework Akka per cercare di farmi un'idea e decidere se sarebbe stato giusto per il mio progetto. Attualmente questa applicazione è una semplice vecchia applicazione java che esegue calcoli molto complessi effettuando chiamate a vari eseguibili esterni in C++ (a volte i calcoli possono richiedere ore per essere eseguiti). Nel codice sembrerebbe qualcosa di simileIl pattern dell'attore con Akka e processi a lunga esecuzione

public static class Worker extends UntypedActor { 
    // Run Very Long Process 
    public void onReceive(Object message) { 
    if (message instanceof Work) { 
     Work work = (Work) message; 
     double result = veryLongProcess(work.getStart(),work.getNrOfElements()); 
     getSender().tell(new Result(result), getSelf()); 
    } else { 
     unhandled(message); 
    } 
    } 
} 

La mia domanda è: Akka può gestire attori che prendono a volte ore per tornare dalla loro esecuzione?

+1

È possibile configurare il dispatcher per essere il modello di thread appropriato per l'applicazione. Probabilmente si desidera impostare un pool di thread separato per il dispatcher che esegue attività lente e lasciare il dispatcher predefinito per gli altri attori che svolgono attività di breve durata. http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html è una buona idea leggere tutti i documenti quando si arriva a un framework così ricco per ottenere la conoscenza di tutte le parti configurabili. – simbo1905

+0

Ok, questo ha senso. Immagino che la mia preoccupazione sia che Akka abbia una sorta di timeout o qualche altra caratteristica del genere che dopo un certo periodo di tempo, l'attore sarebbe morto. –

+0

In base alla mia esperienza, il lavoro si accumula nelle cassette postali degli attori finché non si esaurisce l'heap o i thread. Quindi la gestione delle risorse è qualcosa che devi progettare in altrimenti configurare. Le cose semplici sono cose semplici e complesse sono possibili. Il mio consiglio principale è non rendere tutto un attore. I futures sono anche tuoi amici e usano solo attori per rendere più facile il multitasking e il remoting. – simbo1905

risposta

2

Rispondere direttamente alla domanda; c'è un good article su questo argomento:

Anche in questo caso, se si è di lungo corso calcoli, averli eseguiti in un ExecutionContext separata per le attività della CPU-bound è una buona idea.

L'articolo ha il seguente esempio:

import java.util.concurrent.Executors 
import concurrent.ExecutionContext 

//I added 'private' for the rest of the example 
private val executorService = Executors.newFixedThreadPool(4) 
private val executionContext = ExecutionContext.fromExecutorService(executorService) 

Rispondendo indirettamente,

Futures Prima

Sono completamente d'accordo che attori Akka sono uno strumento molto utile per particolari tipi di lavoro. Per quanto riguarda la memorizzazione nella cache, lo Actors & Agents è il miglior gioco in città.

Tuttavia, in questo caso, suggerirei di utilizzare un Future anziché un attore. È possibile rendere moltoLongProcess una funzione private. La privacy permetterebbe il controllo completo sul numero di thread chiamando il metodo in una sola volta:

def longProcessFut(start : Int, noOfElements : Int) : Future[Result] = Future { 
    veryLongProcess(start, noOfElements) 
}(executionContext)//controls the executing pool of veryLongProcess 

Semplice, conciso, e asincrona.

Nessun omicidio di lettere, nessun metodo di ricezione sovraccarico che accetta nulla sotto il sole, né Puntelli, nemmeno un ActorRef era necessario per il futuro. Bloat, pancia di birra, dico!

Inoltre, l'utente sta per creare un futuro non importa che a causa della ?:

//Actor user code, too verbose 

val longProcessRef = actorSystem actorOf Props[Worker] 

val fut : Future[Result] = (longProcessRef ? Work(0,42)).mapTo[Result] 

rispetto all'utilizzo direttamente

//happy user code 

val fut : Future[Result] = longProcessFut(0, 42) 

stessa straordinaria Future Futures, ma la metà delle calorie!

È possibile controllare il dispatcher del futuro nello stesso modo (s) come suggerito nei commenti, che sono abbastanza buoni. È anche possibile utilizzare actorSystem.dispatcher come dispatcher Future per controllare il comportamento del dispatcher.

+0

Grazie per la risposta impressionante e approfondita! La mia unica domanda rimanente potrebbe essere che tu abbia ancora accesso al modulo remoto di Akka con l'uso di Futures? Avremo un elevato carico di traffico sul sistema e l'obiettivo è di essere in grado di distribuire questi calcoli su n numero di macchine. –

+0

Non sono a conoscenza di alcuna funzionalità per l'esecuzione remota di Futures, quindi gli attori hanno ancora questo vantaggio. Tuttavia, quando eseguo personalmente calcoli distribuiti, utilizzo Apache Spark o Akka Streams (non gli attori direttamente). –

0

Se il lungo in esecuzione logica di business/algoritmo è incrementale, produce risultati intermedi e/o può essere eseguito per molto tempo molto quindi si consiglia di riutilizzare eccellenti frammenti progettuali da qui: Incremental processing in an akka actor