diff --git a/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTestBase.java b/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.java similarity index 76% rename from akka-docs/rst/java/code/docs/pattern/SchedulerPatternTestBase.java rename to akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.java index b2543bfb19..05546232aa 100644 --- a/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTestBase.java +++ b/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.java @@ -8,26 +8,23 @@ import akka.actor.*; import akka.testkit.*; import akka.testkit.TestEvent.Mute; import akka.testkit.TestEvent.UnMute; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.*; import scala.concurrent.util.Duration; import scala.concurrent.util.FiniteDuration; import java.util.Arrays; import java.util.concurrent.TimeUnit; -public class SchedulerPatternTestBase { +public class SchedulerPatternTest { - ActorSystem system; + static ActorSystem system; - @Before - public void setUp() { + @BeforeClass + public static void setUp() { system = ActorSystem.create("SchedulerPatternTest", AkkaSpec.testConf()); } - @After - public void tearDown() { + @AfterClass + public static void tearDown() { system.shutdown(); } @@ -38,9 +35,10 @@ public class SchedulerPatternTestBase { private final Cancellable tick = getContext().system().scheduler().schedule( Duration.create(500, TimeUnit.MILLISECONDS), Duration.create(1000, TimeUnit.MILLISECONDS), - getSelf(), "tick", getContext().system().dispatcher()); + getSelf(), "tick", getContext().dispatcher()); //#schedule-constructor - ActorRef target; + // this variable and constructor is declared here to not show up in the docs + final ActorRef target; public ScheduleInConstructor(ActorRef target) { this.target = target; } @@ -75,7 +73,8 @@ public class SchedulerPatternTestBase { //#schedule-receive public class ScheduleInReceive extends UntypedActor { //#schedule-receive - ActorRef target; + // this variable and constructor is declared here to not show up in the docs + final ActorRef target; public ScheduleInReceive(ActorRef target) { this.target = target; } @@ -85,7 +84,7 @@ public class SchedulerPatternTestBase { public void preStart() { getContext().system().scheduler().scheduleOnce( Duration.create(500, TimeUnit.MILLISECONDS), - getSelf(), "tick", getContext().system().dispatcher()); + getSelf(), "tick", getContext().dispatcher()); } // override postRestart so we don't call preStart and schedule a new message @@ -99,7 +98,7 @@ public class SchedulerPatternTestBase { // send another periodic tick after the specified delay getContext().system().scheduler().scheduleOnce( Duration.create(1000, TimeUnit.MILLISECONDS), - getSelf(), "tick", getContext().system().dispatcher()); + getSelf(), "tick", getContext().dispatcher()); // do something useful here //#schedule-receive target.tell(message, getSelf()); @@ -164,26 +163,29 @@ public class SchedulerPatternTestBase { Iterable filter = Arrays.asList(new akka.testkit.EventFilter[]{ (akka.testkit.EventFilter) new ErrorFilter(ArithmeticException.class)}); - system.eventStream().publish(new Mute(filter)); + try { + system.eventStream().publish(new Mute(filter)); - final ActorRef actor = system.actorOf(props); - new Within(startDuration) { - protected void run() { - probe.expectMsgEquals("tick"); - probe.expectMsgEquals("tick"); - probe.expectMsgEquals("tick"); - } - }; - actor.tell("restart", getRef()); - new Within(afterRestartDuration) { - protected void run() { - probe.expectMsgEquals("tick"); - probe.expectMsgEquals("tick"); - } - }; - system.stop(actor); - - system.eventStream().publish(new UnMute(filter)); + final ActorRef actor = system.actorOf(props); + new Within(startDuration) { + protected void run() { + probe.expectMsgEquals("tick"); + probe.expectMsgEquals("tick"); + probe.expectMsgEquals("tick"); + } + }; + actor.tell("restart", getRef()); + new Within(afterRestartDuration) { + protected void run() { + probe.expectMsgEquals("tick"); + probe.expectMsgEquals("tick"); + } + }; + system.stop(actor); + } + finally { + system.eventStream().publish(new UnMute(filter)); + } } } } diff --git a/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.scala b/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.scala deleted file mode 100644 index d450bbc090..0000000000 --- a/akka-docs/rst/java/code/docs/pattern/SchedulerPatternTest.scala +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Copyright (C) 2009-2012 Typesafe Inc. - */ - -package docs.pattern - -import org.scalatest.junit.JUnitSuite - -class SchedulerPatternTest extends SchedulerPatternTestBase with JUnitSuite diff --git a/akka-docs/rst/java/howto.rst b/akka-docs/rst/java/howto.rst index e1f9f1610b..922d318c75 100644 --- a/akka-docs/rst/java/howto.rst +++ b/akka-docs/rst/java/howto.rst @@ -29,9 +29,12 @@ message sends to the same actor. .. note:: - With this approach the scheduler will be restarted with the actor on restarts. + With this approach the scheduled periodic message send will be restarted with the actor on restarts. + This also means that the time period that elapses between two tick messages during a restart may drift + off based on when you restart the scheduled message sends relative to the time that the last message was + sent, and how long the initial delay is. Worst case scenario is ``interval`` plus ``initialDelay``. -.. includecode:: code/docs/pattern/SchedulerPatternTestBase.java#schedule-constructor +.. includecode:: code/docs/pattern/SchedulerPatternTest.java#schedule-constructor The second variant sets up an initial one shot message send in the ``preStart`` method of the actor, and the then the actor when it receives this message sets up a new one shot @@ -43,7 +46,7 @@ and schedule the initial message send again. With this approach we won't fill up the mailbox with tick messages if the actor is under pressure, but only schedule a new tick message when we have seen the previous one. -.. includecode:: code/docs/pattern/SchedulerPatternTestBase.java#schedule-receive +.. includecode:: code/docs/pattern/SchedulerPatternTest.java#schedule-receive Template Pattern ================ diff --git a/akka-docs/rst/scala/code/docs/pattern/SchedulerPatternSpec.scala b/akka-docs/rst/scala/code/docs/pattern/SchedulerPatternSpec.scala index e79d94b2c5..a669cb0bc5 100644 --- a/akka-docs/rst/scala/code/docs/pattern/SchedulerPatternSpec.scala +++ b/akka-docs/rst/scala/code/docs/pattern/SchedulerPatternSpec.scala @@ -15,10 +15,10 @@ import docs.pattern.SchedulerPatternSpec.ScheduleInConstructor object SchedulerPatternSpec { //#schedule-constructor class ScheduleInConstructor extends Actor { - import context._ - - val tick = system.scheduler.schedule(500 millis, 1000 millis, self, "tick") + val tick = + context.system.scheduler.schedule(500 millis, 1000 millis, self, "tick") //#schedule-constructor + // this var and constructor is declared here to not show up in the docs var target: ActorRef = null def this(target: ActorRef) = { this(); this.target = target } //#schedule-constructor @@ -41,6 +41,7 @@ object SchedulerPatternSpec { class ScheduleInReceive extends Actor { import context._ //#schedule-receive + // this var and constructor is declared here to not show up in the docs var target: ActorRef = null def this(target: ActorRef) = { this(); this.target = target } //#schedule-receive diff --git a/akka-docs/rst/scala/howto.rst b/akka-docs/rst/scala/howto.rst index c5203adb1c..dcdebe06db 100644 --- a/akka-docs/rst/scala/howto.rst +++ b/akka-docs/rst/scala/howto.rst @@ -123,7 +123,10 @@ message sends to the same actor. .. note:: - With this approach the scheduler will be restarted with the actor on restarts. + With this approach the scheduled periodic message send will be restarted with the actor on restarts. + This also means that the time period that elapses between two tick messages during a restart may drift + off based on when you restart the scheduled message sends relative to the time that the last message was + sent, and how long the initial delay is. Worst case scenario is ``interval`` plus ``initialDelay``. .. includecode:: code/docs/pattern/SchedulerPatternSpec.scala#schedule-constructor