Akka: scheduling self-cancelling tasks?

634 views
Skip to first unread message

Haoyi Li

unread,
Jun 3, 2012, 10:47:40 AM6/3/12
to scala-user
I'm trying to schedule tasks which are unique to an object: I want the tasks to happen every so often, but only as long as that object is "active". In order to do this in a generic way, i'm trying to define a thing.schedule, which looks exactly like scheduler.schedule, but kills the task after the object is no longer active:

class thing{
  def schedule(start: Duration, interval: Duration)(task: => Any): Any = {
      val cancellable: Cancellable = Akka.system.scheduler.schedule(start, interval) {
      if (!this.isActive)){
        cancellable.cancel()
      }else{
        task
      }       
    }
  }
}

where this.isActive is some method which returns whether the thing is active. However, I'm getting a 

forward reference extends over definition of value cancellable

Presumable because I'm trying to cancel cancellable, but it hasn't been fully defined within it's own scope.

I would have expected the `task` passed into the scheduler to be able to return some sort of flag (e.g. making it return true/false) to indicate that it should stop, but it doesn't.

I could just place the whole task inside an `if` statement, and the task won't get executed, but then the # of scheduled things will build up unbounded.

Is there a canonical way of doing this? I would think this is a pretty common requirement: scheduling a task contingent until some condition occurs, then killing it forever.

Thanks!
-Haoyi

Alec Zorab

unread,
Jun 9, 2012, 8:57:26 PM6/9/12
to Haoyi Li, scala-user
The akka mailing list is probably a better place to ask this.

However, my normal solution to this problem is something like this:


class thing{
  def schedule(start: Duration, interval: Duration)(task: => Any): Any = {
      val promise = Promise[Unit] 
      val cancellable: Cancellable = Akka.system.scheduler.schedule(start, interval) {
        task()
        if (!this.isActive)
          promise.success(())
      }
      promise.foreach(cancellable.cancel())       
Reply all
Reply to author
Forward
0 new messages