What is the simplest way to delay function execution in Scala, something like JavaScript's setTimeout
? Ideally without spawning thread per delayed execution, i.e. sequential execution. The closest that I was able to find was Akka's Scheduler, but that's an overkill.
For my testing purposes I'm opening thousands of connections, then they get responses in 10 seconds. In node.js it looks like:
http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); setTimeout(function() {res.end('Hello World\n');}, 10000 ); }).listen(8080, '127.0.0.1');
But what would be the closest Scala version of doing the same? I don't care if res.end
is going to be executed in multiple threads or queued in a single one.
defedant is, with intent to obstruct or delay the execution of any decree that may be passed, either about ... with the intention of obstructing or delaying the execution of any decree that may be passed against him.
Conclusion. setTimeout() is a method that will execute a piece of code after the timer has finished running. let timeoutID = setTimeout(function, delay in milliseconds, argument1, argument2,...); The delay is set in milliseconds and 1,000 milliseconds equals 1 second.
The standard way of creating a delay in JavaScript is to use its setTimeout method. For example: console. log("Hello"); setTimeout(() => { console.
Tired of getting flak for answering the question for simplest too simply, here are the standard JVM idioms:
$ scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_65). Type in expressions for evaluation. Or try :help. scala> import java.util.{Timer,TimerTask} import java.util.{Timer, TimerTask} scala> val timer = new Timer timer: java.util.Timer = java.util.Timer@2d9ffd6f scala> def delay(f: () => Unit, n: Long) = timer.schedule(new TimerTask() { def run = f() }, n) delay: (f: () => Unit, n: Long)Unit scala> delay(() => println("Done"), 1000L) scala> Done scala> import java.util.concurrent._ import java.util.concurrent._ scala> val x = Executors.newScheduledThreadPool(2) x: java.util.concurrent.ScheduledExecutorService = java.util.concurrent.ScheduledThreadPoolExecutor@2c5d529e scala> x.schedule(new Callable[Int]() { def call = { println("Ran"); 42 }}, 1L, TimeUnit.SECONDS) res3: java.util.concurrent.ScheduledFuture[Int] = java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@3ab0f534 scala> Ran
There is no API for scheduling a delayed task in the standard library, but you can make an ExecutionContext
with a fixed delay, in order to use Scala Future
.
scala> import scala.concurrent._ import scala.concurrent._ scala> implicit val xx = new ExecutionContext() { | def reportFailure(t: Throwable) = t.printStackTrace() | def execute(r: Runnable) = x.schedule(new Callable[Unit]() { def call = r.run() }, 1L, TimeUnit.SECONDS) | } xx: scala.concurrent.ExecutionContext = $anon$1@40d3ab8b scala> Future(println("hello")) res4: scala.concurrent.Future[Unit] = List() scala> hello scala> Future(42) res5: scala.concurrent.Future[Int] = List() scala> .value res6: Option[scala.util.Try[Int]] = Some(Success(42))
Or you can use Akka's scheduler, which is the canonical answer at Scheduled Executor in Scala
The old one-liner:
Simplest is still just future { blocking(Thread.sleep(10000L)); "done" }
but I wanted to place an ad for this guy, which I just came across, which gives you a progress indicator or intermediate value. I kind of wish it had a different name, is all.
scala> import concurrent._ import concurrent._ scala> import ExecutionContext.Implicits._ import ExecutionContext.Implicits._ scala> import duration._ import duration._ scala> val deadline = 60.seconds.fromNow deadline: scala.concurrent.duration.Deadline = Deadline(38794983852399 nanoseconds) scala> new DelayedLazyVal(() => deadline.timeLeft.max(Duration.Zero), blocking { | Thread.sleep(deadline.timeLeft.toMillis) | Console println "Working!" | }) res9: scala.concurrent.DelayedLazyVal[scala.concurrent.duration.FiniteDuration] = scala.concurrent.DelayedLazyVal@50b56ef3 scala> res9() res10: scala.concurrent.duration.FiniteDuration = 23137149130 nanoseconds scala> res9.isDone res11: Boolean = false scala> res9() res12: scala.concurrent.duration.FiniteDuration = 12499910694 nanoseconds scala> res9() res13: scala.concurrent.duration.FiniteDuration = 5232807506 nanoseconds scala> Working! scala> res9.isDone res14: Boolean = true scala> res9() res15: scala.concurrent.duration.FiniteDuration = 0 days
Here's an alternative formulation with Either, to calculate a value after a delay. Using Left
of course when there is still time Left
.
scala> new DelayedLazyVal(()=> if (deadline.hasTimeLeft) Left(deadline.timeLeft) else | Right("Working!"), blocking(Thread.sleep(deadline.timeLeft.toMillis))) res21: scala.concurrent.DelayedLazyVal[Product with Serializable with scala.util.Either[scala.concurrent.duration.FiniteDuration,String]] = scala.concurrent.DelayedLazyVal@78f9c6f2 scala> res21() res22: Product with Serializable with scala.util.Either[scala.concurrent.duration.FiniteDuration,String] = Left(28553649064 nanoseconds) scala> res21() res23: Product with Serializable with scala.util.Either[scala.concurrent.duration.FiniteDuration,String] = Left(9378334087 nanoseconds) scala> res21.isDone res24: Boolean = false scala> res21() res25: Product with Serializable with scala.util.Either[scala.concurrent.duration.FiniteDuration,String] = Right(Working!) scala> res21.isDone res26: Boolean = true
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