Berechnung mit Zeitlimit

8

Ich versuche ein Konstrukt zu schreiben, mit dem ich Berechnungen in einem bestimmten Zeitfenster ausführen kann. Etwas wie:

%Vor%

Hier wird timeLimited expensiveComputation mit einem Timeout von 45 Minuten ausführen. Wenn das Zeitlimit erreicht wird, wird None zurückgegeben, andernfalls wurde das Ergebnis in Some eingeschlossen.

Ich suche nach einer Lösung, die:

  • Ist ziemlich billig in Leistung und Erinnerung;
  • Führt die zeitlich begrenzte Aufgabe im aktuellen Thread aus.

Irgendwelche Vorschläge?

BEARBEITEN

Ich verstehe, dass mein ursprüngliches Problem keine Lösung hat. Angenommen, ich kann einen Thread für die Berechnung erstellen (aber ich bevorzuge keinen threadpool / executor / dispatcher). Was ist der schnellste, sicherste und sauberste Weg?

    
paradigmatic 04.10.2011, 16:47
quelle

9 Antworten

8

Führt den angegebenen Codeblock aus oder gibt beim Timeout eine Ausnahme aus:

%Vor%     
gruenewa 04.10.2011, 19:18
quelle
3

Nur eine Idee: Ich bin nicht so vertraut mit akka-Futures . Aber vielleicht ist es möglich, den zukünftigen ausführenden Thread an den aktuellen Thread anzuhängen und akka futures mit Timeouts zu verwenden?

    
Peter Schmitz 04.10.2011 17:19
quelle
2

gibt entweder (die Berechnungsaufrufe für einen Scheduler) oder Sie verwenden einen Thread , der von "außen" manipuliert wird.

    
ziggystar 04.10.2011 18:23
quelle
1

Wenn Sie die Aufgabe im aktuellen Thread ausführen möchten und keine anderen Threads beteiligt sein sollten, müssten Sie innerhalb von expensiveComputation überprüfen, ob das Zeitlimit überschritten ist. Wenn beispielsweise expensiveComputation eine Schleife ist, können Sie nach jeder Iteration nach der Zeit suchen.

    
Kim Stebel 04.10.2011 17:00
quelle
1

Wenn der Code von expensiveComputation in Ordnung ist, können Sie Thread.interrupted() häufig überprüfen, ziemlich einfach. Aber ich nehme an, du bist es nicht.

Ich glaube nicht, dass es eine Lösung gibt, die für beliebigen expensiveComputation Code funktioniert. Die Frage ist, was Sie bereit sind, als Einschränkung auf teurereComputation zu haben.

Sie haben den veralteten und ziemlich unsicheren Thead.stop(Throwable) auch. Wenn Ihr Code kein Objekt außer den von ihm selbst erstellten ändert, funktioniert es möglicherweise.

    
Didier Dupont 04.10.2011 17:01
quelle
1

Ich sah ein solches Muster gut für zeitlich begrenzte Aufgaben (Java-Code):

%Vor%

Die Funktion checkTimeout() ist günstig zu telefonieren; Sie fügen es dem Code hinzu, so dass es einigermaßen oft aufgerufen wird, aber nicht zu oft. Es wird nur die aktuelle Zeit mit dem Timer-Wert überprüft, der durch setTimeout() plus dem Timeout-Wert festgelegt wurde. Wenn die aktuelle Zeit diesen Wert überschreitet, erhöht checkTimeout() TimeoutException .

Ich hoffe, dass diese Logik auch in Scala reproduziert werden kann.

    
9000 04.10.2011 17:12
quelle
1

Verwenden Sie für eine generische Lösung (ohne den Verlust jeder Ihrer teurenComputationen mit checkTimeout () -Code verwenden) möglicherweise Javassist. Ссылка
Sie können dann verschiedene checkTimeout () -Methoden dynamisch einfügen.
Hier ist der Einleitungstext auf ihrer Website:

Javaassist (Java Programming Assistant) vereinfacht die Java-Bytecode-Manipulation. Es ist eine Klassenbibliothek zum Editieren von Bytecodes in Java; Es ermöglicht Java-Programmen, zur Laufzeit eine neue Klasse zu definieren und eine Klassendatei zu ändern, wenn die JVM sie lädt. Im Gegensatz zu anderen ähnlichen Bytecode-Editoren stellt Javassist zwei API-Ebenen bereit: Quellniveau und Bytecode. Wenn die Benutzer die API auf Quellcodeebene verwenden, können sie eine Klassendatei bearbeiten, ohne die Spezifikationen des Java-Bytecodes zu kennen. Die gesamte API wurde nur mit dem Vokabular der Sprache Java entwickelt. Sie können sogar eingefügten Bytecode in Form von Quelltext angeben; Javassist kompiliert es im laufenden Betrieb. Auf der anderen Seite erlaubt die API auf Bytecode-Ebene den Benutzern, eine Klassendatei direkt als andere Editoren zu bearbeiten.

Aspektorientierte Programmierung: Javassist kann ein gutes Werkzeug zum Hinzufügen neuer Methoden zu einer Klasse und zum Einfügen von Ratschlägen vor / nach / um sowohl auf der aufrufenden als auch auf der aufgerufenen Seite sein.

Reflexion: Eine der Anwendungen von Javassist ist die Laufzeitreflexion; Javassist ermöglicht Java-Programmen, ein Metaobjekt zu verwenden, das Methodenaufrufe auf Objekten auf Basisebene steuert. Kein spezialisierter Compiler oder virtuelle Maschine wird benötigt.

    
n4rzul 05.10.2011 07:54
quelle
0

Im aktuellen Thread ?? Phhew ... Überprüfen Sie nach jedem Berechnungsschritt Nun, wenn Ihre "teure Berechnung" in mehrere Schritte aufgeteilt werden kann oder iterative Logik hat, können Sie die Zeit beim Start erfassen und dann periodisch zwischen Ihren Schritten überprüfen. Dies ist keine generische Lösung, wird aber funktionieren.

Bei einer allgemeineren Lösung können Sie Aspekte oder die Annotationsverarbeitung verwenden, die Ihren Code automatisch mit diesen Überprüfungen belegt. Wenn der "Check" Ihnen sagt, dass Ihre Zeit abgelaufen ist, geben Sie None zurück.

Ill denke mit Hilfe von Annotationen und einem Annotationsprozessor schnell an eine Lösung in Java ...

%Vor%     
n4rzul 04.10.2011 17:06
quelle
0

Wenn Sie dies sehr ernsthaft benötigen, könnten Sie ein Compiler-Plugin erstellen, das Prüfblöcke in Schleifen und Bedingungen einfügt. Diese Prüfblöcke können Thread.isInterrupted () überprüfen und eine Exception auslösen, um zu entkommen.

Sie könnten möglicherweise eine Annotation, d. h. @interruptible, verwenden, um die Methoden zur Verbesserung zu markieren.

    
thoredge 04.10.2011 18:45
quelle

Tags und Links