2012-06-11 22:12:45 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package akka.cluster
|
|
|
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit
|
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
|
|
|
import java.util.concurrent.atomic.AtomicLong
|
|
|
|
|
|
|
|
|
|
import akka.actor.Scheduler
|
2012-06-29 13:33:20 +02:00
|
|
|
import scala.concurrent.util.Duration
|
2012-06-11 22:12:45 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* INTERNAL API
|
|
|
|
|
*/
|
|
|
|
|
private[akka] object FixedRateTask {
|
|
|
|
|
def apply(scheduler: Scheduler, initalDelay: Duration, delay: Duration)(f: ⇒ Unit): FixedRateTask = {
|
|
|
|
|
new FixedRateTask(scheduler, initalDelay, delay, new Runnable { def run(): Unit = f })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* INTERNAL API
|
|
|
|
|
*
|
|
|
|
|
* Task to be scheduled periodically at a fixed rate, compensating, on average,
|
|
|
|
|
* for inaccuracy in scheduler. It will start when constructed, using the
|
|
|
|
|
* initialDelay.
|
|
|
|
|
*/
|
|
|
|
|
private[akka] class FixedRateTask(scheduler: Scheduler, initalDelay: Duration, delay: Duration, task: Runnable) extends Runnable {
|
|
|
|
|
|
2012-06-12 13:37:21 +02:00
|
|
|
private val delayNanos = delay.toNanos
|
2012-06-11 22:12:45 +02:00
|
|
|
private val cancelled = new AtomicBoolean(false)
|
|
|
|
|
private val counter = new AtomicLong(0L)
|
2012-06-12 13:37:21 +02:00
|
|
|
private val startTime = System.nanoTime + initalDelay.toNanos
|
2012-06-11 22:12:45 +02:00
|
|
|
scheduler.scheduleOnce(initalDelay, this)
|
|
|
|
|
|
|
|
|
|
def cancel(): Unit = cancelled.set(true)
|
|
|
|
|
|
|
|
|
|
override final def run(): Unit = if (!cancelled.get) try {
|
|
|
|
|
task.run()
|
|
|
|
|
} finally if (!cancelled.get) {
|
2012-06-12 13:37:21 +02:00
|
|
|
val nextTime = startTime + delayNanos * counter.incrementAndGet
|
|
|
|
|
// it's ok to schedule with negative duration, will run asap
|
|
|
|
|
val nextDelay = Duration(nextTime - System.nanoTime, TimeUnit.NANOSECONDS)
|
2012-06-11 22:12:45 +02:00
|
|
|
try {
|
|
|
|
|
scheduler.scheduleOnce(nextDelay, this)
|
|
|
|
|
} catch { case e: IllegalStateException ⇒ /* will happen when scheduler is closed, nothing wrong */ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|