18

In Java I can use Scheduled Executor to schedule tasks to run after a given delay. I can use it in Scala but I wonder if there is a Scala API for that.

Is there any Scala API (as opposed to Scheduled Executor in Java) to schedule tasks?

Michael
  • 41,026
  • 70
  • 193
  • 341

4 Answers4

36

Akka has something similar with schedulers:

http://doc.akka.io/api/akka/2.1.4/#akka.actor.Scheduler

You can obtain one from the actor system:

val actorSystem = ActorSystem()
val scheduler = actorSystem.scheduler
val task = new Runnable { def run() { log.info("Hello") } }
implicit val executor = actorSystem.dispatcher

scheduler.schedule(
  initialDelay = Duration(5, TimeUnit.SECONDS),
  interval = Duration(10, TimeUnit.SECONDS),
  runnable = task)

If you are using Akka or something based on it, like Play, that would be the way to go.

Marius Danila
  • 10,311
  • 2
  • 34
  • 37
  • 31
    Why do people think Scala == Akka? – jimmy_terra Jan 23 '17 at 06:48
  • 2
    Ohh thank you for writing that.. I am new to Scala and everytime I Google anything about Scala, I am finding answers related to Akka.. Your comment makes it much clear for me. – akki Jan 02 '19 at 10:18
  • @marius This works for me only with the `println` function. Do I need to do something else to make it work for any other functions (specifically, a method of the same class). – akki Jan 03 '19 at 09:15
  • Looks like this wasn't working for me in the controllers layer for an `Action.async` type class method. Don't really know the reason for that but it worked for me in another layer of the project. – akki Jan 08 '19 at 10:25
  • 2
    Akka is like a virus. – nilskp Jan 15 '19 at 16:17
9

I have been looking for a scala api for scheduled execution as well.

Java's ScheduledExecutor:

  • uses a thread pool for running the scheduler and operating the timeouts, and so does not require a Thread per timeout
  • No akka needed

I wrote a little scala wrapper for the single task scheduling. See the gist: https://gist.github.com/platy/8f0e634c64d9fb54559c

MikeB
  • 928
  • 9
  • 24
4

You can use scalaz's Task,

import scala.concurrent.duration.{FiniteDuration, SECONDS}
import scalaz.concurrent.Task
Task.schedule(Console.println("time's up"), FiniteDuration(5, SECONDS)).runAsync { _ => }
Sheng
  • 1,697
  • 4
  • 19
  • 33
4

As an alternative, there is Monix scheduler too: https://monix.io/docs/3x/execution/scheduler.html

It use a Java's Scheduled Executor behind, but it is wrapped and transparent.

You need to implement some Runnable to be executed, which is lighter than Akka Actor.

For example, you can do (taken from the documentation):

lazy val scheduler =
  Scheduler.singleThread(name="my-thread")

// First execution in 3 seconds, then every 5 seconds
val c = scheduler.scheduleAtFixedRate(
  3, 5, TimeUnit.SECONDS,
  new Runnable {
    def run(): Unit = {
      println("Fixed delay task")
    }
  })

// If we change our mind and want to cancel
c.cancel()
JR Utily
  • 1,792
  • 1
  • 23
  • 38