I am trying to implement scheduled future in Scala. I would like it to wait specific time and then execute the body. So far I tried the following, simple approach
val d = 5.seconds.fromNow val f = future {Await.ready(Promise().future, d.timeLeft); 1} val res = Await.result(f, Duration.Inf)
but I am getting the TimeoutExcpetion on the future. Is this even the correct approach or should I simply use the ScheduledExecutor from Java?
By default, futures and promisesfutures and promisesIn other cases a future and a promise are created together and associated with each other: the future is the value, the promise is the function that sets the value – essentially the return value (future) of an asynchronous function (promise).https://en.wikipedia.org › wiki › Futures_and_promisesFutures and promises - Wikipedia are non-blocking, making use of callbacks instead of typical blocking operations. To simplify the use of callbacks both syntactically and conceptually, Scala provides combinators such as flatMap , foreach , and filter used to compose futures in a non-blocking way.
FutureFutureIn other cases a future and a promise are created together and associated with each other: the future is the value, the promise is the function that sets the value – essentially the return value (future) of an asynchronous function (promise).https://en.wikipedia.org › wiki › Futures_and_promisesFutures and promises - Wikipedia represents a result of an asynchronous computation that may or may not be available yet. When we create a new Future, Scala spawns a new thread and executes its code. Once the execution is finished, the result of the computation (value or exception) will be assigned to the Future.
Promise is an object which can be completed with a value or failed with an exception. A promise should always eventually be completed, whether for success or failure, in order to avoid unintended resource retention for any associated Futures' callbacks or transformations. Source Promise.scala. AnyRef, Any.
You can't unwrap the value of a Future because a Future represents the result of an asynchronous computation that may or may not be available yet. By default, futures and non-blocking, encouraging the use of callbacks instead of typical blocking operations.
Akka has akka.pattern:
def after[T](duration: FiniteDuration, using: Scheduler)(value: ⇒ Future[T])(implicit ec: ExecutionContext): Future[T]
"Returns a scala.concurrent.Future that will be completed with the success or failure of the provided value after the specified duration."
http://doc.akka.io/api/akka/2.2.1/#akka.pattern.package
There is nothing to do that out of the box using the standard library alone. For most simple use cases, you can use a little helper such as this:
object DelayedFuture { import java.util.{Timer, TimerTask} import java.util.Date import scala.concurrent._ import scala.concurrent.duration.FiniteDuration import scala.util.Try private val timer = new Timer(true) private def makeTask[T]( body: => 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). ctx.execute( new Runnable { def run() { prom.complete(Try(body)) } } ) } } ) prom.future } def apply[T]( delay: Long )( body: => T )(implicit ctx: ExecutionContext): Future[T] = { makeTask( body )( timer.schedule( _, delay ) ) } def apply[T]( date: Date )( body: => T )(implicit ctx: ExecutionContext): Future[T] = { makeTask( body )( timer.schedule( _, date ) ) } def apply[T]( delay: FiniteDuration )( body: => T )(implicit ctx: ExecutionContext): Future[T] = { makeTask( body )( timer.schedule( _, delay.toMillis ) ) } }
This can be used like this:
import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits._ DelayedFuture( 5 seconds )( println("Hello") )
Note that unlike java scheduled futures, this implementation will not let you cancel the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With