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:
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?
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?
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.
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.
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.
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.
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%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.