2017-07-04 4 views
0

Ich bin ziemlich neu in Scala und habe einen Hintergrund in Java.Scala: Verzögerung Code Block Ausführung oder Abbrechen

Das Problem, mit dem ich konfrontiert bin, ist, dass ich eine Funktion nach 5 Minuten ausführen möchte. Und kann dies auch jederzeit abbrechen.

In Java würde ich grundsätzlich TimerTask verwenden, und es auf 5 min. Wenn ich stornieren möchte, rufe ich einfach cancel Methode an. Das Schöne ist, ich kann diese Java-Klasse in Scala verwenden. Aber da ich immer noch Scala lerne, frage ich mich nur, ob mir eine bessere Möglichkeit fehlt, das besser zu machen. Ich lief in Future und Await.result Scala Klassen, aber ich habe eine harte Zeit herauszufinden.

Irgendwelche Ratschläge?

Antwort

1

Normalerweise, wenn Sie irgendeine Art von Rahmen verwenden, wäre es seine eigene Abstraktion liefern um geplante Aufgaben zu bewältigen. Finagle hat eine Timer Klasse, basierend auf Nettys HashedWheelTimer zum Beispiel, Akka hat Scheduler, etc. (Es ist eine gute Idee, das gleiche Scheduling-Framework in der gesamten Anwendung zu verwenden, weil das eine effizientere Nutzung von Ressourcen ermöglicht).

Wenn Sie gerade "Vanille" Scala-Code ohne Rahmen schreiben, ist nichts falsch daran, nur TimerTask direkt zu verwenden oder vielleicht einen kleinen Wrapper darum herum, so dass es nicht so umständlich ist, in Scala-Code zu verwenden :

val someTask = FutureTask 
    .schedule(5 seconds) { println("Hello!") } 
someTask.onComplete { result => println("Completed with " + result) } 
someTask.cancel 
Await.result(someTask, 2 seconds) 

usw.

+0

Eigentlich ist das, was Sie gesagt haben, interessant: "(Es ist eine gute Idee, das gleiche Scheduling-Framework in der gesamten Anwendung zu verwenden, da dies eine effizientere Nutzung der Ressourcen ermöglicht)" Wir sind eigentlich Akka für Ich werde unsere ereignisbasierte App verwalten, und diese Timeout-Implementierung, die ich durchführen muss, wird in dieser Umgebung stattfinden. Ich bin gerade auf etwas Interessantes von Akka gestoßen: http://doc.akka.io/docs/akka/snapshot/scala/scheduler .html Scheint wie ich bin ganz eingestellt;) –

+0

Was ich sage ist _always_ interessant – Dima

2

Die Future in der Scala-Bibliothek kann nicht abgebrochen werden. Was Sie tun müssten, wäre eine Art von Bedingung zu implementieren und sicherzustellen, dass Sie "Ding" nur so lange ausführen, wie diese Bedingung erfüllt ist.

Sie könnten monix.Task aussehen wollen, die kündbar ist: https://monix.io/docs/2x/eval/task.html

Aus ihrer docs:

import monix.eval.Task 
import monix.execution.CancelableFuture 
import concurrent.duration._ 

val task = Task(1 + 1).delayExecution(1.second) 

val result: CancelableFuture[Int] = 
    task.runAsync 

// If we change our mind 
result.cancel() 
+0

es klingt wie es die Arbeit machen würde, werde ich einige Tests chec gehen implementieren:

class FutureTask[T](f: => Future[T]) extends TimerTask { val promise = Promise[T]() def run(): Unit = promise.completeWith(f) override def cancel() = { val result = super.cancel if(result) promise.complete(Failure(new CancellationException)) result } } object FutureTask { implicit def toFuture[T](task: FutureTask[T]) = task.promise.future def scheduleFlat[T](when: Duration)(f: => Future[T])(implicit timer: Timer = defaultTimer): FutureTask[T] = { val task = new FutureTask(f) timer.schedule(task, when.toMillis) task } def schedule[T](when: Duration)(f: => T)(implicit timer: Timer = defaultTimer, ctx: ExecutionContext): FutureTask[T] = scheduleFlat(when)(Future(f))(timer) val defaultTimer = new java.util.Timer(true) } 

Jetzt können Sie Dinge wie tun k it out;) –