Skip to content

Instantly share code, notes, and snippets.

@arturopala
Created February 3, 2021 00:42
Show Gist options
  • Save arturopala/5ab72e5144c968d3d32f74640af38563 to your computer and use it in GitHub Desktop.
Save arturopala/5ab72e5144c968d3d32f74640af38563 to your computer and use it in GitHub Desktop.
import java.util.{Timer, TimerTask}
import java.util.Date
import scala.concurrent._
import scala.concurrent.duration.FiniteDuration
import scala.util.Try
import scala.util.Success
import scala.util.Failure
object Schedule {
def apply[T](delay: Long)(body: => Future[T])(implicit ctx: ExecutionContext): Future[T] =
makeTask(body)(timer.schedule(_, delay))
def apply[T](date: Date)(body: => Future[T])(implicit ctx: ExecutionContext): Future[T] =
makeTask(body)(timer.schedule(_, date))
def apply[T](
delay: FiniteDuration
)(body: => Future[T])(implicit ctx: ExecutionContext): Future[T] =
makeTask(body)(timer.schedule(_, delay.toMillis))
private val timer = new Timer(true)
private def makeTask[T](
body: => Future[T]
)(schedule: TimerTask => Unit)(implicit ctx: ExecutionContext): Future[T] = {
val prom = Promise[T]()
schedule(
new TimerTask {
def run() {
// IMPORTANT: The timer task just starts the execution on the passed
// ExecutionContext and is thus almost instantaneous (making it
// practical to use a single Timer - hence a single background thread).
body.transform(
{ result: T =>
prom.complete(Success(result))
result
},
{ error: Throwable =>
prom.complete(Failure(error))
error
}
)
}
}
)
prom.future
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment