2015-11-13 11 views
5

In letzter Zeit habe ich das großartige Akka-Framework untersucht, um zu versuchen, ein Gefühl dafür zu bekommen und zu entscheiden, ob es für mein Projekt richtig wäre. Derzeit ist diese Anwendung eine einfache alte Java-Anwendung, die einige sehr komplexe Berechnungen durchführt, indem sie Aufrufe an verschiedene externe C++ - Programmdateien ausführt (manchmal können die Berechnungen Stunden dauern). Im Code würde es in etwa so aussehenDas Schauspieler-Muster mit Akka und lang laufenden Prozessen

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

Meine Frage ist, kann Akka Akteure behandeln nehmen manchmal Stunden von ihrer Hinrichtung zurück?

+1

Sie können die Konfiguration Dispatcher, um das geeignete Thread-Modell für Ihre Anwendung zu sein. Wahrscheinlich möchten Sie einen separaten Thread-Pool für den Dispatcher einrichten, der langsame Aufgaben ausführt, und den Standard-Dispatcher für andere Akteure, die kurzlebige Aufgaben ausführen, belassen. http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html Es ist eine gute Idee, alle Dokumente zu lesen, wenn Sie zu einem so umfangreichen Framework kommen, um sich über alle konfigurierbaren Teile zu informieren. – simbo1905

+0

Ok, das macht Sinn. Ich glaube, meine Sorge ist, dass Akka irgendeine Art von Zeitüberschreitung oder eine andere solche Eigenschaft hat, dass nach einer gewissen verstrichenen Zeit annehmen würde, dass der Schauspieler gestorben ist. –

+0

Nach meiner Erfahrung tankt sich die Arbeit in den Postern des Schauspielers so lange auf, bis du keinen Haufen mehr hast. Ressourcenmanagement ist also etwas, was Sie sonst noch konfigurieren müssen. Einfache Dinge sind einfach, komplexe Dinge sind möglich. Mein oberster Tipp ist, mach nicht alles zu einem Schauspieler. Futures sind auch deine Freunde und verwenden nur Schauspieler, um Multitasking und Remoting zu erleichtern. – simbo1905

Antwort

2

Beantworten Sie Ihre Frage direkt; gibt es eine good article an diesem Thema:

Noch einmal, wenn Sie Berechnungen mit langer Laufzeit, mit ihnen in einem separaten ExecutionContext für CPU-gebundenen Aufgaben auszuführen sind eine gute Idee.

Der Artikel hat das folgende Beispiel:

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) 

Answering indirekt

Futures Erste

bin ich völlig einverstanden, dass Akka Schauspieler sind ein sehr nützliches Werkzeug für bestimmte Arten von Arbeit. Wenn es um Caching geht, sind Actors & Agents das beste Spiel in der Stadt.

In diesem Fall würde ich jedoch die Verwendung eines Future anstelle eines Actor vorschlagen. Sie könnten sehr LongProcess eine private Funktion machen. Die Privatsphäre würde vollständige Kontrolle über die Anzahl der Threads ermöglichen, die die Methode auf einmal aufrufen:

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

Einfach, prägnant und asynchron.

Kein Töten von Briefen, keine überladene Methode, die alles unter der Sonne akzeptiert, noch Props, nicht einmal ein ActorRef war für die Zukunft notwendig. Aufgeblasen, Bierbauch sag ich!

Außerdem wird Ihre Benutzer gehen eine Zukunft, egal was wegen ? erstellen: zur Verwendung von Futures direkt

//happy user code 

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

gleicher großer Zukunft, aber die Hälfte der Kalorien

//Actor user code, too verbose 

val longProcessRef = actorSystem actorOf Props[Worker] 

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

Im Vergleich!

Sie können den Dispatcher der Zukunft auf die gleiche Weise steuern, wie in den Kommentaren vorgeschlagen, die ziemlich gut sind. Sie können sogar actorSystem.dispatcher als Ihren zukünftigen Dispatcher verwenden, um das Dispatcher-Verhalten zu steuern.

+0

Danke für die tolle und gründliche Antwort! Meine eine verbleibende Frage wäre, könntest du immer noch Zugang zum Remoting-Modul von Akka mit Futures haben? Wir werden eine hohe Verkehrslast auf dem System haben und das Ziel ist es, diese Berechnungen auf eine Anzahl von Maschinen verteilen zu können. –

+0

Ich bin mir keiner Funktionalität bewusst, um Futures fern zu betreiben, also haben Actors immer noch diesen Vorteil. Wenn ich persönlich verteilte Berechnungen mache, benutze ich Apache Spark oder Akka Streams (nicht Actors direkt). –

0

Wenn der langen laufende Geschäftslogik/Algorithmus inkrementalen ist, produzieren Zwischenergebnisse und/oder kann für ein sehr lange läuft dann können Sie von hier ausgezeichnetem Design-Schnipsel wieder zu verwenden: Incremental processing in an akka actor

Verwandte Themen