Search code examples
scalaakkascheduleractorschedule

How to stop a system.scheduler.schedule in Scala Akka


I currently have a method in place that creates a scheduler to send a message to my actors on set intervals. However, I am now trying to implement new functionality for a system shutdown.

I am able to stop the Actor in which these schedulers are created, but this does not stop the schedulers.

private def initialiseTask(taskName: String, taskActorRef: ActorRef, interval: FiniteDuration,
                             startDelay: FiniteDuration = 0 milliseconds, message: Any = "tick"): Unit = {
    logger.debug(s"Initialising task: $taskName")
    system.scheduler.schedule(startDelay,
      interval,
      taskActorRef,
      message)
    logger.debug(s"$taskName initialised")
  }

And as you can imagine, in the method is called for each actor I want to create a schedule for once this actor has started up. I have used schedulers before and cancelled them by assigning them to a val, and then using .cancel() on them, however, given this scheduler is used to schedule multiple things, I am unsure how I can cancel this.

Thanks for any help!


Solution

  • To cancel a scheduled send, you need to save the Cancellable which the scheduler gives you when you call schedule.

    Since you're scheduling in an actor, the logical place for this would be as part of the state of the actor: you can later send a message to the actor to tell it to cancel the scheduled sends.

    A Map is probably the most suitable structure for storing the Cancellables. If you're not going to be reusing taskName, then it would make a fine key (i.e. you'd have a Map[String, Cancellable]), or maybe you might want to include taskActorRef or message as well.

    How specifically one would do this depends on the style of actor definition (e.g. is it using the FSM DSL, or context.become, or tracking state via vars?).