Flash Death
Flash Death

Reputation: 89

Scala - How to stop a futures executed with a akka scheduler

this is my first time asking a question here and I am relatively new to scala. I have the following chunk of code:

implicit val context = ExecutionContext.fromExecutor(Executors.newSingleThreadExecutor())
val system = ActorSystem("My System")

val update = future {
  def doSomething(args...) = {
    // Do Stuff
  }

  val result = system.scheduler.schedule(Duration.create(delay, TimeUnit.MILLISECONDS),
    Duration.create(interval, TimeUnit.MILLISECONDS))(doSomething(args...))
}

I need the doSomething function to be executed many times and the above code meets my needs, but under certain circumstances I will need to stop it.

So my question is what is the best way to go about stopping the scheduler? Thanks in advance.

Upvotes: 1

Views: 3314

Answers (2)

Soumya Simanta
Soumya Simanta

Reputation: 11741

Why do you have a scheduler inside a Future? I believe you can do the same using a Java Timer task without creating an ActorSystem. I mean I don't understand the reason why you want to use Actors to invoke a Future when you are not using the core features of Actors. Maybe I'm missing something.

Here is one way of doing it. You can send a message cancelSomethingMsg to your actor that will cancel the scheduler. The scheduler itself sends a message to itself at the scheduled frequency.

object MyActor {
   case object doSomethingMsg
   case object cancelSomethingMsg 
}

class MyActor extends Actor {
  private var cancellable: Option[Cancellable] = None

  override def preStart() = {
    //schedule a message doSomethingMsg to self every 5 seconds
    cancellable = Option(context.system.scheduler.schedule(5 seconds, duration, self, doSomethingMsg))
  }

  override def postStop() = {
    cancellable.foreach(_.cancel())
    cancellable = None
  }

  def doSomethingF = { future {//make sure you don't close over mutable state of the actor inside this Future} }

  def receive = {
     case doSomethingMsg => doSomethingF() 
     case doCancelMsg => cancellable.foreach(_.cancel())

  }    
}

Upvotes: 4

maks
maks

Reputation: 6006

Your result val is of type Cancellable, you can just cancel it. But I believe that it cancels between executions, not when it is executing doSomething method

Upvotes: 2

Related Questions