diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-05-23 03:22:01 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-05-23 03:22:01 -0700 |
commit | 0f198a63d2f1a141b43f40f639d5fff8697510d0 (patch) | |
tree | a00c180516a2714ea5107547eae766c82a799f05 /test/files/jvm | |
parent | cebf241ad87358b0e8d2804750a4ac36e76f7091 (diff) | |
parent | 033463f87fe71e8f6d5b17f7cb82b8c2ea5f5271 (diff) | |
download | scala-0f198a63d2f1a141b43f40f639d5fff8697510d0.tar.gz scala-0f198a63d2f1a141b43f40f639d5fff8697510d0.tar.bz2 scala-0f198a63d2f1a141b43f40f639d5fff8697510d0.zip |
Merge pull request #575 from vjovanov/actors-migration-kit
Adding the Actor Migration Kit.
Diffstat (limited to 'test/files/jvm')
22 files changed, 1293 insertions, 0 deletions
diff --git a/test/files/jvm/actmig-PinS.check b/test/files/jvm/actmig-PinS.check new file mode 100644 index 0000000000..97d1c5be02 --- /dev/null +++ b/test/files/jvm/actmig-PinS.check @@ -0,0 +1,18 @@ +I'm acting! +I'm acting! +I'm acting! +I'm acting! +I'm acting! +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +That is the question. +That is the question. +That is the question. +That is the question. +That is the question. +received message: hi there +received message: 15 +Got an Int: 12 diff --git a/test/files/jvm/actmig-PinS.scala b/test/files/jvm/actmig-PinS.scala new file mode 100644 index 0000000000..db5713dde4 --- /dev/null +++ b/test/files/jvm/actmig-PinS.scala @@ -0,0 +1,118 @@ +import scala.actors._ + +import scala.actors.Actor._ + +/* PinS, Listing 32.1: A simple actor + */ +object SillyActor extends Actor { + def act() { + for (i <- 1 to 5) { + println("I'm acting!") + //Thread.sleep(1000) + Thread.sleep(10) + } + } +} + +object SeriousActor extends Actor { + def act() { + for (i <- 1 to 5) { + println("To be or not to be.") + //Thread.sleep(1000) + Thread.sleep(10) + } + } +} + +/* PinS, Listing 32.3: An actor that calls react + */ +object NameResolver extends Actor { + import java.net.{InetAddress, UnknownHostException} + + def act() { + react { + case (name: String, actor: Actor) => + actor ! getIp(name) + act() + case "EXIT" => + println("Name resolver exiting.") + // quit + case msg => + println("Unhandled message: " + msg) + act() + } + } + + def getIp(name: String): Option[InetAddress] = { + try { + Some(InetAddress.getByName(name)) + } catch { + case _: UnknownHostException => None + } + } + +} + +object Test extends App { + + /* PinS, Listing 32.2: An actor that calls receive + */ + def makeEchoActor(): Actor = actor { + while (true) { + receive { + case 'stop => + exit() + case msg => + println("received message: " + msg) + } + } + } + + /* PinS, page 696 + */ + def makeIntActor(): Actor = actor { + receive { + case x: Int => // I only want Ints + println("Got an Int: " + x) + } + } + + + actor { + self.trapExit = true + self.link(SillyActor) + SillyActor.start() + + react { + case Exit(SillyActor, _) => + self.link(SeriousActor) + SeriousActor.start() + react { + case Exit(SeriousActor, _) => + // PinS, page 694 + val seriousActor2 = actor { + for (i <- 1 to 5) + println("That is the question.") + //Thread.sleep(1000) + Thread.sleep(10) + } + + Thread.sleep(200) + val echoActor = makeEchoActor() + self.link(echoActor) + echoActor ! "hi there" + echoActor ! 15 + echoActor ! 'stop + + react { + case Exit(_, _) => + val intActor = makeIntActor() + intActor ! "hello" + intActor ! math.Pi + // only the following send leads to output + intActor ! 12 + } + } + } + } +} diff --git a/test/files/jvm/actmig-PinS_1.check b/test/files/jvm/actmig-PinS_1.check new file mode 100644 index 0000000000..97d1c5be02 --- /dev/null +++ b/test/files/jvm/actmig-PinS_1.check @@ -0,0 +1,18 @@ +I'm acting! +I'm acting! +I'm acting! +I'm acting! +I'm acting! +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +That is the question. +That is the question. +That is the question. +That is the question. +That is the question. +received message: hi there +received message: 15 +Got an Int: 12 diff --git a/test/files/jvm/actmig-PinS_1.scala b/test/files/jvm/actmig-PinS_1.scala new file mode 100644 index 0000000000..d203526513 --- /dev/null +++ b/test/files/jvm/actmig-PinS_1.scala @@ -0,0 +1,130 @@ +import scala.actors._ + +object SillyActor { + val ref = MigrationSystem.actorOf(Props(() => new SillyActor, "akka.actor.default-stash-dispatcher")) +} + +/* PinS, Listing 32.1: A simple actor + */ +class SillyActor extends Actor { + def act() { + for (i <- 1 to 5) { + println("I'm acting!") + Thread.sleep(10) + } + } +} + +object SeriousActor { + val ref = MigrationSystem.actorOf(Props(() => new SeriousActor, "akka.actor.default-stash-dispatcher")) +} + +class SeriousActor extends Actor { + def act() { + for (i <- 1 to 5) { + println("To be or not to be.") + //Thread.sleep(1000) + Thread.sleep(10) + } + } +} + +/* PinS, Listing 32.3: An actor that calls react + */ +object NameResolver extends Actor { + import java.net.{ InetAddress, UnknownHostException } + + def act() { + react { + case (name: String, actor: Actor) => + actor ! getIp(name) + act() + case "EXIT" => + println("Name resolver exiting.") + // quit + case msg => + println("Unhandled message: " + msg) + act() + } + } + + def getIp(name: String): Option[InetAddress] = { + try { + Some(InetAddress.getByName(name)) + } catch { + case _: UnknownHostException => None + } + } + +} + +object Test extends App { + + /* PinS, Listing 32.2: An actor that calls receive + */ + def makeEchoActor(): ActorRef = MigrationSystem.actorOf(Props(() => new Actor { + def act() { + while (true) { + receive { + case 'stop => + exit() + case msg => + println("received message: " + msg) + } + } + } + }, "akka.actor.default-stash-dispatcher")) + + /* PinS, page 696 + */ + def makeIntActor(): ActorRef = MigrationSystem.actorOf(Props(() => new Actor { + def act() { + receive { + case x: Int => // I only want Ints + println("Got an Int: " + x) + } + } + }, "akka.actor.default-stash-dispatcher")) + + MigrationSystem.actorOf(Props(() => new Actor { + def act() { + trapExit = true + link(SillyActor.ref) + react { + case Exit(_: SillyActor, _) => + link(SeriousActor.ref) + react { + case Exit(_: SeriousActor, _) => + // PinS, page 694 + val seriousActor2 = MigrationSystem.actorOf(Props(() => + new Actor { + def act() { + for (i <- 1 to 5) { + println("That is the question.") + //Thread.sleep(1000) + Thread.sleep(10) + } + } + } + , "akka.actor.default-stash-dispatcher")) + + Thread.sleep(200) + val echoActor = makeEchoActor() + link(echoActor) + echoActor ! "hi there" + echoActor ! 15 + echoActor ! 'stop + + react { + case Exit(_, _) => + val intActor = makeIntActor() + intActor ! "hello" + intActor ! math.Pi + // only the following send leads to output + intActor ! 12 + } + } + } + } + }, "akka.actor.default-stash-dispatcher")) +} diff --git a/test/files/jvm/actmig-PinS_2.check b/test/files/jvm/actmig-PinS_2.check new file mode 100644 index 0000000000..97d1c5be02 --- /dev/null +++ b/test/files/jvm/actmig-PinS_2.check @@ -0,0 +1,18 @@ +I'm acting! +I'm acting! +I'm acting! +I'm acting! +I'm acting! +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +That is the question. +That is the question. +That is the question. +That is the question. +That is the question. +received message: hi there +received message: 15 +Got an Int: 12 diff --git a/test/files/jvm/actmig-PinS_2.scala b/test/files/jvm/actmig-PinS_2.scala new file mode 100644 index 0000000000..9f52cca369 --- /dev/null +++ b/test/files/jvm/actmig-PinS_2.scala @@ -0,0 +1,150 @@ +import scala.actors.{ MigrationSystem, StashingActor, ActorRef, Props, Exit } + +object SillyActor { + val ref = MigrationSystem.actorOf(Props(() => new SillyActor, "default-stash-dispatcher")) +} + +/* PinS, Listing 32.1: A simple actor + */ +class SillyActor extends StashingActor { + + def receive = { case _ => println("Nop") } + + override def act() { + for (i <- 1 to 5) { + println("I'm acting!") + Thread.sleep(10) + } + } +} + +object SeriousActor { + val ref = MigrationSystem.actorOf(Props(() => new SeriousActor, "default-stash-dispatcher")) +} + +class SeriousActor extends StashingActor { + def receive = { case _ => println("Nop") } + override def act() { + for (i <- 1 to 5) { + println("To be or not to be.") + Thread.sleep(10) + } + } +} + +/* PinS, Listing 32.3: An actor that calls react + */ +object NameResolver { + val ref = MigrationSystem.actorOf(Props(() => new NameResolver, "default-stash-dispatcher")) +} + +class NameResolver extends StashingActor { + import java.net.{ InetAddress, UnknownHostException } + + def receive = { case _ => println("Nop") } + + override def act() { + react { + case (name: String, actor: ActorRef) => + actor ! getIp(name) + act() + case "EXIT" => + println("Name resolver exiting.") + // quit + case msg => + println("Unhandled message: " + msg) + act() + } + } + + def getIp(name: String): Option[InetAddress] = { + try { + Some(InetAddress.getByName(name)) + } catch { + case _: UnknownHostException => None + } + } + +} + +object Test extends App { + + /* PinS, Listing 32.2: An actor that calls receive + */ + def makeEchoActor(): ActorRef = MigrationSystem.actorOf(Props(() => + new StashingActor { + def receive = { case _ => println("Nop") } + + override def act() { + loop { + react { + case 'stop => + exit() + case msg => + println("received message: " + msg) + } + } + } + }, "default-stash-dispatcher")) + + /* PinS, page 696 + */ + def makeIntActor(): ActorRef = MigrationSystem.actorOf(Props(() =>new StashingActor { + + def receive = { case _ => println("Nop") } + + override def act() { + react { + case x: Int => // I only want Ints + println("Got an Int: " + x) + } + } + }, "default-stash-dispatcher")) + + MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { case _ => println("Nop") } + + override def act() { + trapExit = true + link(SillyActor.ref) + react { + case Exit(_: SillyActor, _) => + link(SeriousActor.ref) + react { + case Exit(_: SeriousActor, _) => + // PinS, page 694 + val seriousActor2 = MigrationSystem.actorOf(Props(() =>{ + new StashingActor { + + def receive = { case _ => println("Nop") } + + override def act() { + for (i <- 1 to 5) { + println("That is the question.") + Thread.sleep(10) + } + } + } + }, "default-stash-dispatcher")) + + Thread.sleep(200) + val echoActor = makeEchoActor() + link(echoActor) + echoActor ! "hi there" + echoActor ! 15 + echoActor ! 'stop + + react { + case Exit(_, _) => + val intActor = makeIntActor() + intActor ! "hello" + intActor ! math.Pi + // only the following send leads to output + intActor ! 12 + } + } + } + } + }, "default-stash-dispatcher")) +} diff --git a/test/files/jvm/actmig-PinS_3.check b/test/files/jvm/actmig-PinS_3.check new file mode 100644 index 0000000000..bdbdf8a692 --- /dev/null +++ b/test/files/jvm/actmig-PinS_3.check @@ -0,0 +1,19 @@ +I'm acting! +I'm acting! +I'm acting! +I'm acting! +I'm acting! +Post stop +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +To be or not to be. +That is the question. +That is the question. +That is the question. +That is the question. +That is the question. +received message: hi there +received message: 15 +Got an Int: 12 diff --git a/test/files/jvm/actmig-PinS_3.scala b/test/files/jvm/actmig-PinS_3.scala new file mode 100644 index 0000000000..047bf53c32 --- /dev/null +++ b/test/files/jvm/actmig-PinS_3.scala @@ -0,0 +1,159 @@ +import scala.actors.{ MigrationSystem, StashingActor, ActorRef, Terminated, Props } + +object SillyActor { + val ref = MigrationSystem.actorOf(Props(() => new SillyActor, "default-stash-dispatcher")) +} + +/* PinS, Listing 32.1: A simple actor + */ +class SillyActor extends StashingActor { + def receive = { case _ => println("Why are you not dead"); context.stop(self) } + + override def preStart() { + for (i <- 1 to 5) { + println("I'm acting!") + Thread.sleep(10) + } + context.stop(self) + } + + override def postStop() { + println("Post stop") + } +} + +object SeriousActor { + val ref = MigrationSystem.actorOf(Props(() => new SeriousActor, "default-stash-dispatcher")) +} + +class SeriousActor extends StashingActor { + def receive = { case _ => println("Nop") } + override def preStart() { + for (i <- 1 to 5) { + println("To be or not to be.") + //Thread.sleep(1000) + Thread.sleep(10) + } + context.stop(self) + } +} + +/* PinS, Listing 32.3: An actor that calls react + */ +object NameResolver { + val ref = MigrationSystem.actorOf(Props(() => new NameResolver, "default-stash-dispatcher")) +} + +class NameResolver extends StashingActor { + import java.net.{ InetAddress, UnknownHostException } + + def receive = { + case (name: String, actor: ActorRef) => + actor ! getIp(name) + case "EXIT" => + println("Name resolver exiting.") + context.stop(self) // quit + case msg => + println("Unhandled message: " + msg) + } + + def getIp(name: String): Option[InetAddress] = { + try { + Some(InetAddress.getByName(name)) + } catch { + case _: UnknownHostException => None + } + } + +} + +object Test extends App { + + /* PinS, Listing 32.2: An actor that calls receive + */ + def makeEchoActor(): ActorRef = MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { // how to handle receive + case 'stop => + context.stop(self) + case msg => + println("received message: " + msg) + } + }, "default-stash-dispatcher")) + + /* PinS, page 696 + */ + def makeIntActor(): ActorRef = MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { + case x: Int => // I only want Ints + unstashAll() + println("Got an Int: " + x) + context.stop(self) + case _ => stash() + } + }, "default-stash-dispatcher")) + + MigrationSystem.actorOf(Props(() => new StashingActor { + val silly = SillyActor.ref + + override def preStart() { + context.watch(SillyActor.ref) + } + + def receive = { + case Terminated(`silly`) => + unstashAll() + val serious = SeriousActor.ref + context.watch(SeriousActor.ref) + context.become { + case Terminated(`serious`) => + // PinS, page 694 + val seriousActor2 = MigrationSystem.actorOf(Props(() => { + new StashingActor { + + def receive = { case _ => context.stop(self) } + + override def preStart() = { + for (i <- 1 to 5) { + println("That is the question.") + //Thread.sleep(1000) + Thread.sleep(10) + } + context.stop(self) + } + } + }, "default-stash-dispatcher")) + + Thread.sleep(200) + val echoActor = makeEchoActor() + context.watch(echoActor) + echoActor ! "hi there" + echoActor ! 15 + echoActor ! 'stop + + context.become { + case Terminated(_) => + unstashAll() + val intActor = makeIntActor() + intActor ! "hello" + intActor ! math.Pi + // only the following send leads to output + intActor ! 12 + context.unbecome() + context.unbecome() + context.stop(self) + case m => + println("Stash 1 " + m) + stash(m) + } + case m => + println("Stash 2 " + m) + stash(m) + } + case m => + println("Stash 3 " + m) + stash(m) + } + }, "default-stash-dispatcher")) +} diff --git a/test/files/jvm/actmig-hierarchy.check b/test/files/jvm/actmig-hierarchy.check new file mode 100644 index 0000000000..317e9677c3 --- /dev/null +++ b/test/files/jvm/actmig-hierarchy.check @@ -0,0 +1,2 @@ +hello +hello diff --git a/test/files/jvm/actmig-hierarchy.scala b/test/files/jvm/actmig-hierarchy.scala new file mode 100644 index 0000000000..7277329d85 --- /dev/null +++ b/test/files/jvm/actmig-hierarchy.scala @@ -0,0 +1,44 @@ +import scala.actors._ + + +class ReactorActor extends Reactor[String] { + def act() { + var cond = true + loopWhile(cond) { + react { + case x if x == "hello1" => println(x.dropRight(1)) + case "exit" => cond = false + } + } + } +} + +class ReplyActor extends ReplyReactor { + def act() { + var cond = true + loopWhile(cond) { + react { + case "hello" => println("hello") + case "exit" => cond = false; + } + } + } +} + + + +object Test { + + def main(args: Array[String]) { + val reactorActor = new ReactorActor + val replyActor = new ReplyActor + reactorActor.start() + replyActor.start() + + reactorActor ! "hello1" + replyActor ! "hello" + + reactorActor ! "exit" + replyActor ! "exit" + } +} diff --git a/test/files/jvm/actmig-hierarchy_1.check b/test/files/jvm/actmig-hierarchy_1.check new file mode 100644 index 0000000000..317e9677c3 --- /dev/null +++ b/test/files/jvm/actmig-hierarchy_1.check @@ -0,0 +1,2 @@ +hello +hello diff --git a/test/files/jvm/actmig-hierarchy_1.scala b/test/files/jvm/actmig-hierarchy_1.scala new file mode 100644 index 0000000000..559ebe7b11 --- /dev/null +++ b/test/files/jvm/actmig-hierarchy_1.scala @@ -0,0 +1,41 @@ +import scala.actors._ + +class ReactorActor extends Actor { + def act() { + var cond = true + loopWhile(cond) { + react { + case x: String if x == "hello1" => println(x.dropRight(1)) + case "exit" => cond = false + } + } + } +} + +class ReplyActor extends Actor { + def act() { + var cond = true + loopWhile(cond) { + react { + case "hello" => println("hello") + case "exit" => cond = false; + } + } + } +} + +object Test { + + def main(args: Array[String]) { + val reactorActor = new ReactorActor + val replyActor = new ReplyActor + reactorActor.start() + replyActor.start() + + reactorActor ! "hello1" + replyActor ! "hello" + + reactorActor ! "exit" + replyActor ! "exit" + } +} diff --git a/test/files/jvm/actmig-instantiation.check b/test/files/jvm/actmig-instantiation.check new file mode 100644 index 0000000000..4c13d5c0a1 --- /dev/null +++ b/test/files/jvm/actmig-instantiation.check @@ -0,0 +1,8 @@ +OK error: java.lang.RuntimeException: In order to create StashingActor one must use actorOf. +OK error: java.lang.RuntimeException: Only one actor can be created per actorOf call. +0 +100 +200 +300 +400 +500 diff --git a/test/files/jvm/actmig-instantiation.scala b/test/files/jvm/actmig-instantiation.scala new file mode 100644 index 0000000000..4170dbd3ad --- /dev/null +++ b/test/files/jvm/actmig-instantiation.scala @@ -0,0 +1,91 @@ +import scala.actors.MigrationSystem._ +import scala.actors.Actor._ +import scala.actors.{ Actor, StashingActor, ActorRef, Props, MigrationSystem, PoisonPill } +import java.util.concurrent.{ TimeUnit, CountDownLatch } +import scala.collection.mutable.ArrayBuffer + +class TestStashingActor extends StashingActor { + + def receive = { case v: Int => Test.append(v); Test.latch.countDown() } + +} + +object Test { + val NUMBER_OF_TESTS = 5 + + // used for sorting non-deterministic output + val buff = ArrayBuffer[Int](0) + val latch = new CountDownLatch(NUMBER_OF_TESTS) + val toStop = ArrayBuffer[ActorRef]() + + def append(v: Int) = synchronized { + buff += v + } + + def main(args: Array[String]) = { + // plain scala actor + val a1 = actor { + react { case v: Int => Test.append(v); Test.latch.countDown() } + } + a1 ! 100 + + // simple instantiation + val a2 = MigrationSystem.actorOf(Props(() => new TestStashingActor, "akka.actor.default-stash-dispatcher")) + a2 ! 200 + toStop += a2 + + // actor of with scala actor + val a3 = actorOf(Props(() => actor { + react { case v: Int => Test.append(v); Test.latch.countDown() } + }, "akka.actor.default-stash-dispatcher")) + a3 ! 300 + + // using the manifest + val a4 = actorOf(Props(() => new TestStashingActor, "akka.actor.default-stash-dispatcher")) + a4 ! 400 + toStop += a4 + + // deterministic part of a test + // creation without actorOf + try { + val a3 = new TestStashingActor + a3 ! -1 + } catch { + case e => println("OK error: " + e) + } + + // actorOf double creation + try { + val a3 = actorOf(Props(() => { + new TestStashingActor + new TestStashingActor + }, "akka.actor.default-stash-dispatcher")) + a3 ! -1 + } catch { + case e => println("OK error: " + e) + } + + // actorOf nesting + try { + val a5 = actorOf(Props(() => { + val a6 = actorOf(Props(() => new TestStashingActor, "akka.actor.default-stash-dispatcher")) + toStop += a6 + new TestStashingActor + }, "akka.actor.default-stash-dispatcher")) + + a5 ! 500 + toStop += a5 + } catch { + case e => println("Should not throw an exception: " + e) + } + + // output + latch.await(200, TimeUnit.MILLISECONDS) + if (latch.getCount() > 0) { + println("Error: Tasks have not finished!!!") + } + + buff.sorted.foreach(println) + toStop.foreach(_ ! PoisonPill) + } +} diff --git a/test/files/jvm/actmig-loop-react.check b/test/files/jvm/actmig-loop-react.check new file mode 100644 index 0000000000..7b955aa9b9 --- /dev/null +++ b/test/files/jvm/actmig-loop-react.check @@ -0,0 +1,16 @@ +do task +do task +do task +do task +working +scala got exception +working +akka got exception +do task 1 +do string I am a String +do task 42 +after react +Terminated +do task 1 +do string I am a String +do task 42 diff --git a/test/files/jvm/actmig-loop-react.scala b/test/files/jvm/actmig-loop-react.scala new file mode 100644 index 0000000000..8452f9766a --- /dev/null +++ b/test/files/jvm/actmig-loop-react.scala @@ -0,0 +1,170 @@ +import scala.actors.MigrationSystem._ +import scala.actors.Actor._ +import scala.actors.{ Actor, StashingActor, ActorRef, Props, MigrationSystem, PoisonPill } +import java.util.concurrent.{ TimeUnit, CountDownLatch } +import scala.collection.mutable.ArrayBuffer + +object Test { + + def testLoopWithConditionReact() = { + // Snippet showing composition of receives + // Loop with Condition Snippet - before + val myActor = actor { + var c = true + loopWhile(c) { + react { + case x: Int => + // do task + println("do task") + if (x == 42) c = false + } + } + } + + myActor.start() + myActor ! 1 + myActor ! 42 + + // Loop with Condition Snippet - migrated + val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { + case x: Int => + // do task + println("do task") + if (x == 42) context.stop(self) + } + }, "default-stashing-dispatcher")) + myAkkaActor ! 1 + myAkkaActor ! 42 + } + + def testNestedReact() = { + // Snippet showing composition of receives + // Loop with Condition Snippet - before + val myActor = actor { + var c = true + loopWhile(c) { + react { + case x: Int => + // do task + println("do task " + x) + if (x == 42) c = false + else + react { + case y: String => + println("do string " + y) + } + println("after react") + } + } + } + myActor.start() + + myActor ! 1 + myActor ! "I am a String" + myActor ! 42 + + Thread.sleep(100) + println(myActor.getState) + + // Loop with Condition Snippet - migrated + val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { + case x: Int => + // do task + println("do task " + x) + if (x == 42) + context.stop(self) + else + context.become(({ + case y: String => + println("do string " + y) + }: Receive).andThen(x => { + unstashAll() + context.unbecome() + }).orElse { case x => stash() }) + } + }, "default-stashing-dispatcher")) + + myAkkaActor ! 1 + myAkkaActor ! "I am a String" + myAkkaActor ! 42 + + } + + def exceptionHandling() = { + // Stashing actor with act and exception handler + val myActor = MigrationSystem.actorOf(Props(() => new StashingActor { + + def receive = { case _ => println("Dummy method.") } + override def act() = { + loop { + react { + case "fail" => + throw new Exception("failed") + case "work" => + println("working") + case "die" => + exit() + } + } + } + + override def exceptionHandler = { + case x: Exception => println("scala got exception") + } + + }, "default-stashing-dispatcher")) + + myActor ! "work" + myActor ! "fail" + myActor ! "die" + + Thread.sleep(100) + // Stashing actor in Akka style + val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor { + def receive = PFCatch({ + case "fail" => + throw new Exception("failed") + case "work" => + println("working") + case "die" => + context.stop(self) + }, { case x: Exception => println("akka got exception") }) + }, "default-stashing-dispatcher")) + + myAkkaActor ! "work" + myAkkaActor ! "fail" + myAkkaActor ! "die" + } + + def main(args: Array[String]) = { + testLoopWithConditionReact() + Thread.sleep(100) + exceptionHandling() + Thread.sleep(100) + testNestedReact() + } + +} + +// As per Jim Mcbeath blog (http://jim-mcbeath.blogspot.com/2008/07/actor-exceptions.html) +class PFCatch(f: PartialFunction[Any, Unit], handler: PartialFunction[Exception, Unit]) + extends PartialFunction[Any, Unit] { + + def apply(x: Any) = { + try { + f(x) + } catch { + case e: Exception if handler.isDefinedAt(e) => handler(e) + } + } + + def isDefinedAt(x: Any) = f.isDefinedAt(x) +} + +object PFCatch { + def apply(f: PartialFunction[Any, Unit], handler: PartialFunction[Exception, Unit]) = new PFCatch(f, handler) +} diff --git a/test/files/jvm/actmig-public-methods.check b/test/files/jvm/actmig-public-methods.check new file mode 100644 index 0000000000..bb6530c926 --- /dev/null +++ b/test/files/jvm/actmig-public-methods.check @@ -0,0 +1,6 @@ +None +Some(bang qmark after 1) +bang +bang qmark after 0 +bang qmark in future after 0 +typed bang qmark in future after 0 diff --git a/test/files/jvm/actmig-public-methods.scala b/test/files/jvm/actmig-public-methods.scala new file mode 100644 index 0000000000..c4c8560122 --- /dev/null +++ b/test/files/jvm/actmig-public-methods.scala @@ -0,0 +1,69 @@ +import scala.collection.mutable.ArrayBuffer +import scala.actors.Actor._ +import scala.actors._ +import scala.actors.MigrationSystem +import scala.util.continuations._ +import java.util.concurrent.{ TimeUnit, CountDownLatch } + +object Test { + val NUMBER_OF_TESTS = 6 + + // used for sorting non-deterministic output + val buff = ArrayBuffer[String]() + val latch = new CountDownLatch(NUMBER_OF_TESTS) + val toStop = ArrayBuffer[Actor]() + + def append(v: String) = synchronized { + buff += v + } + + def main(args: Array[String]) = { + + val respActor = actor { + loop { + react { + case (x: String, time: Long) => + Thread.sleep(time) + reply(x + " after " + time) + case str: String => + append(str) + latch.countDown() + case _ => exit() + } + } + } + + toStop += respActor + + respActor ! ("bang") + + val res1 = respActor !? (("bang qmark", 0L)) + append(res1.toString) + latch.countDown() + + val res2 = respActor !? (200, ("bang qmark", 1L)) + append(res2.toString) + latch.countDown() + + val res21 = respActor !? (1, ("bang qmark", 200L)) + append(res21.toString) + latch.countDown() + + val fut1 = respActor !! (("bang qmark in future", 0L)) + append(fut1().toString()) + latch.countDown() + + val fut2 = respActor !! (("typed bang qmark in future", 0L), { case x: String => x }) + append(fut2()) + latch.countDown() + + // output + latch.await(10, TimeUnit.MILLISECONDS) + if (latch.getCount() > 0) { + println("Error: Tasks have not finished!!!") + } + + buff.sorted.foreach(println) + toStop.foreach(_ ! 'stop) + } +} diff --git a/test/files/jvm/actmig-public-methods_1.check b/test/files/jvm/actmig-public-methods_1.check new file mode 100644 index 0000000000..bb6530c926 --- /dev/null +++ b/test/files/jvm/actmig-public-methods_1.check @@ -0,0 +1,6 @@ +None +Some(bang qmark after 1) +bang +bang qmark after 0 +bang qmark in future after 0 +typed bang qmark in future after 0 diff --git a/test/files/jvm/actmig-public-methods_1.scala b/test/files/jvm/actmig-public-methods_1.scala new file mode 100644 index 0000000000..41798c4c37 --- /dev/null +++ b/test/files/jvm/actmig-public-methods_1.scala @@ -0,0 +1,88 @@ +import scala.collection.mutable.ArrayBuffer +import scala.actors.Actor._ +import scala.actors._ +import scala.util._ +import java.util.concurrent.{ TimeUnit, CountDownLatch } +import scala.concurrent.util.Duration +import scala.actors.pattern._ + +object Test { + val NUMBER_OF_TESTS = 6 + + // used for sorting non-deterministic output + val buff = ArrayBuffer[String]() + val latch = new CountDownLatch(NUMBER_OF_TESTS) + val toStop = ArrayBuffer[ActorRef]() + + def append(v: String) = synchronized { + buff += v + } + + def main(args: Array[String]) = { + + val respActor = MigrationSystem.actorOf(Props(() => actor { + loop { + react { + case (x: String, time: Long) => + Thread.sleep(time) + reply(x + " after " + time) + case str: String => + append(str) + latch.countDown() + case x => + exit() + } + } + }, "akka.actor.default-stash-dispatcher")) + + toStop += respActor + + respActor ! "bang" + + implicit val timeout = Timeout(Duration(200, TimeUnit.MILLISECONDS)) + val msg = ("bang qmark", 0L) + val res1 = respActor.?(msg)(Timeout(Duration.Inf)) + append(res1().toString) + latch.countDown() + + val msg1 = ("bang qmark", 1L) + val res2 = respActor.?(msg1)(Timeout(Duration(200, TimeUnit.MILLISECONDS))) + append((res2() match { + case x: AskTimeoutException => None + case v => Some(v) + }).toString) + latch.countDown() + + // this one should time out + val msg11 = ("bang qmark", 200L) + val res21 = respActor.?(msg11)(Timeout(Duration(1, TimeUnit.MILLISECONDS))) + append((res21() match { + case x: AskTimeoutException => None + case v => Some(v) + }).toString) + latch.countDown() + + val msg2 = ("bang qmark in future", 0L) + val fut1 = respActor.?(msg2)(Duration.Inf) + append(fut1().toString()) + latch.countDown() + + val handler: PartialFunction[Any, String] = { + case x: String => x.toString + } + + val msg3 = ("typed bang qmark in future", 0L) + val fut2 = (respActor.?(msg3)(Duration.Inf)) + append(Futures.future { handler.apply(fut2()) }().toString) + latch.countDown() + + // output + latch.await(10, TimeUnit.MILLISECONDS) + if (latch.getCount() > 0) { + println("Error: Tasks have not finished!!!") + } + + buff.sorted.foreach(println) + toStop.foreach(_ ! PoisonPill) + } +} diff --git a/test/files/jvm/actmig-react-receive.check b/test/files/jvm/actmig-react-receive.check new file mode 100644 index 0000000000..cc2a426e68 --- /dev/null +++ b/test/files/jvm/actmig-react-receive.check @@ -0,0 +1,16 @@ +do before +do task +do after +do before +do task +do after +do before +do task +do in between +do string +do after +do before +do task +do in between +do string +do after diff --git a/test/files/jvm/actmig-react-receive.scala b/test/files/jvm/actmig-react-receive.scala new file mode 100644 index 0000000000..fbc10a8d52 --- /dev/null +++ b/test/files/jvm/actmig-react-receive.scala @@ -0,0 +1,104 @@ +import scala.actors.MigrationSystem._ +import scala.actors.Actor._ +import scala.actors.{ Actor, StashingActor, ActorRef, Props, MigrationSystem, PoisonPill } +import java.util.concurrent.{ TimeUnit, CountDownLatch } +import scala.collection.mutable.ArrayBuffer + +object Test { + + def testComposition() = { + // Snippet showing composition of receives + // React Snippet - before + val myActor = actor { + // do before + println("do before") + receive { + case x: Int => + // do task + println("do task") + } + println("do in between") + receive { + case x: String => + // do string now + println("do string") + } + println("do after") + } + myActor.start() + myActor ! 1 + myActor ! "1" + Thread.sleep(200) + // React Snippet - migrated + val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor { + override def preStart() = { + println("do before") + } + + def receive = ({ + case x: Int => + // do task + println("do task") + }: Receive) andThen { v => + context.become { + case x: String => + //do string + println("do string") + context.stop(self) + } + println("do in between") + } + + override def postStop() = { + println("do after") + } + + }, "default-stashing-dispatcher")) + myAkkaActor ! 1 + myAkkaActor ! "1" + Thread.sleep(200) + } + + def main(args: Array[String]) = { + // React Snippet - before + val myActor = actor { + // do before + println("do before") + receive { + case x: Int => + // do task + println("do task") + } + println("do after") + } + myActor.start() + myActor ! 1 + + Thread.sleep(200) + + // React Snippet - migrated + val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor { + override def preStart() = { + println("do before") + } + + def receive = { + case x: Int => + // do task + println("do task") + context.stop(self) + } + + override def postStop() = { + println("do after") + } + + }, "default-stashing-dispatcher")) + myAkkaActor ! 1 + + Thread.sleep(200) + // Starting composition test + testComposition() + + } +} |