=act #18346 Document scheduler task throws

This commit is contained in:
Patrik Nordwall 2015-09-10 17:03:18 +02:00
parent a22b3be9da
commit 9e8168479a
4 changed files with 33 additions and 2 deletions

View file

@ -17,6 +17,7 @@ import org.scalatest.BeforeAndAfterEach
import com.typesafe.config.{ Config, ConfigFactory } import com.typesafe.config.{ Config, ConfigFactory }
import akka.pattern.ask import akka.pattern.ask
import akka.testkit._ import akka.testkit._
import scala.util.control.NoStackTrace
object SchedulerSpec { object SchedulerSpec {
val testConfRevolver = ConfigFactory.parseString(""" val testConfRevolver = ConfigFactory.parseString("""
@ -78,6 +79,19 @@ trait SchedulerSpec extends BeforeAndAfterEach with DefaultTimeout with Implicit
expectNoMsg(500 millis) expectNoMsg(500 millis)
} }
"stop continuous scheduling if the task throws exception" taggedAs TimingTest in {
val count = new AtomicInteger(0)
collectCancellable(system.scheduler.schedule(0 milliseconds, 20.millis) {
val c = count.incrementAndGet()
testActor ! c
if (c == 3) throw new RuntimeException("TEST") with NoStackTrace
})
expectMsg(1)
expectMsg(2)
expectMsg(3)
expectNoMsg(500 millis)
}
"schedule once" taggedAs TimingTest in { "schedule once" taggedAs TimingTest in {
case object Tick case object Tick
val countDownLatch = new CountDownLatch(3) val countDownLatch = new CountDownLatch(3)

View file

@ -74,6 +74,9 @@ trait Scheduler {
* of the function executions). In such cases, the actual execution interval * of the function executions). In such cases, the actual execution interval
* will differ from the interval passed to this method. * will differ from the interval passed to this method.
* *
* If the function throws an exception the repeated scheduling is aborted,
* i.e. the function will not be invoked any more.
*
* Scala API * Scala API
*/ */
final def schedule( final def schedule(
@ -83,7 +86,7 @@ trait Scheduler {
schedule(initialDelay, interval, new Runnable { override def run = f }) schedule(initialDelay, interval, new Runnable { override def run = f })
/** /**
* Schedules a function to be run repeatedly with an initial delay and * Schedules a `Runnable` to be run repeatedly with an initial delay and
* a frequency. E.g. if you would like the function to be run after 2 * a frequency. E.g. if you would like the function to be run after 2
* seconds and thereafter every 100ms you would set delay = Duration(2, * seconds and thereafter every 100ms you would set delay = Duration(2,
* TimeUnit.SECONDS) and interval = Duration(100, TimeUnit.MILLISECONDS). If * TimeUnit.SECONDS) and interval = Duration(100, TimeUnit.MILLISECONDS). If
@ -93,6 +96,8 @@ trait Scheduler {
* the actual execution interval will differ from the interval passed to this * the actual execution interval will differ from the interval passed to this
* method. * method.
* *
* If the `Runnable` throws an exception the repeated scheduling is aborted,
* i.e. the function will not be invoked any more.
* *
* Java API * Java API
*/ */
@ -287,6 +292,10 @@ class LightArrayRevolverScheduler(config: Config,
case SchedulerException(msg) throw new IllegalStateException(msg) case SchedulerException(msg) throw new IllegalStateException(msg)
} }
/**
* Shutdown the scheduler. All scheduled task will be executed when the scheduler closed,
* i.e. the task may execute before its timeout.
*/
override def close(): Unit = Await.result(stop(), getShutdownTimeout) foreach { override def close(): Unit = Await.result(stop(), getShutdownTimeout) foreach {
task task
try task.run() catch { try task.run() catch {
@ -372,7 +381,7 @@ class LightArrayRevolverScheduler(config: Config,
tickNanos - 1 // rounding up tickNanos - 1 // rounding up
) / tickNanos).toInt // and converting to slot number ) / tickNanos).toInt // and converting to slot number
// tick is an Int that will wrap around, but toInt of futureTick gives us modulo operations // tick is an Int that will wrap around, but toInt of futureTick gives us modulo operations
// and the difference (offset) will be correct in any case // and the difference (offset) will be correct in any case
val offset = futureTick - tick val offset = futureTick - tick
val bucket = futureTick & wheelMask val bucket = futureTick & wheelMask
node.value.ticks = offset node.value.ticks = offset

View file

@ -62,6 +62,10 @@ From ``akka.actor.ActorSystem``
.. includecode:: ../../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala .. includecode:: ../../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala
:include: scheduler :include: scheduler
.. warning::
All scheduled task will be executed when the ``ActorSystem`` is terminated, i.e.
the task may execute before its timeout.
The Scheduler Interface for Implementors The Scheduler Interface for Implementors
---------------------------------------- ----------------------------------------

View file

@ -50,6 +50,10 @@ From ``akka.actor.ActorSystem``
.. includecode:: ../../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala .. includecode:: ../../../akka-actor/src/main/scala/akka/actor/ActorSystem.scala
:include: scheduler :include: scheduler
.. warning::
All scheduled task will be executed when the ``ActorSystem`` is terminated, i.e.
the task may execute before its timeout.
The Scheduler interface The Scheduler interface
----------------------- -----------------------