Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - ScheduledFuture

Tags:

scala

future

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?

like image 239
Bober02 Avatar asked May 03 '13 13:05

Bober02


People also ask

Is Scala Future blocking?

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.

How does Scala Future work?

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.

What are Scala promises?

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.

How do you unwrap the Future?

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.


2 Answers

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

like image 144
Viktor Klang Avatar answered Oct 13 '22 00:10

Viktor Klang


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.

like image 30
Régis Jean-Gilles Avatar answered Oct 12 '22 23:10

Régis Jean-Gilles