Skip to content

Commit 2de9ab8

Browse files
committed
Merge pull request scala#1291 from vjovanov/actor-migration-tests
Fix for SI-6305 & new actor migration tests
2 parents fe3fa3d + cc56187 commit 2de9ab8

16 files changed

+404
-11
lines changed

src/actors-migration/scala/actors/MigrationSystem.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
package scala.actors
1+
package scala.actors.migration
22

3+
import scala.actors._
34
import scala.collection._
45

56
object MigrationSystem {
67

7-
private[actors] val contextStack = new ThreadLocal[immutable.Stack[Boolean]] {
8+
private[migration] val contextStack = new ThreadLocal[immutable.Stack[Boolean]] {
89
override def initialValue() = immutable.Stack[Boolean]()
910
}
1011

src/actors-migration/scala/actors/Pattern.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package scala.actors
1+
package scala.actors.migration
22

3+
import scala.actors._
34
import scala.concurrent.util.Duration
45
import scala.language.implicitConversions
56

src/actors-migration/scala/actors/Props.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
package scala.actors
1+
package scala.actors.migration
2+
3+
import scala.actors._
24

35
/**
46
* ActorRef configuration object. It represents the minimal subset of Akka Props class.

src/actors-migration/scala/actors/StashingActor.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
package scala.actors
1+
package scala.actors.migration
22

3+
import scala.actors._
4+
import scala.actors.Actor._
35
import scala.collection._
46
import scala.concurrent.util.Duration
57
import java.util.concurrent.TimeUnit

src/actors-migration/scala/actors/Timeout.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
** |/ **
77
\* */
88

9-
package scala.actors
9+
package scala.actors.migration
1010

1111
import scala.concurrent.util.Duration
1212
import java.util.concurrent.TimeUnit

test/files/jvm/actmig-PinS_1.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import scala.actors._
2+
import scala.actors.migration._
23
import scala.concurrent.util.duration._
34
import scala.concurrent.{ Promise, Await }
45

test/files/jvm/actmig-PinS_2.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import scala.actors.{ MigrationSystem, StashingActor, ActorRef, Props, Exit }
1+
import scala.actors._
2+
import scala.actors.migration._
23
import scala.concurrent.util.duration._
34
import scala.concurrent.{ Promise, Await }
45

test/files/jvm/actmig-PinS_3.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import scala.actors.{ MigrationSystem, StashingActor, ActorRef, Terminated, Props }
1+
import scala.actors._
2+
import scala.actors.migration._
23
import scala.concurrent.util.duration._
34
import scala.concurrent.{ Promise, Await }
45

test/files/jvm/actmig-loop-react.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ after react
1313
do task 1
1414
do string I am a String
1515
do task 42
16+
after react
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import scala.actors.migration.MigrationSystem._
2+
import scala.actors.Actor._
3+
import scala.actors._
4+
import scala.actors.migration._
5+
import java.util.concurrent.{ TimeUnit, CountDownLatch }
6+
import scala.collection.mutable.ArrayBuffer
7+
import scala.concurrent.util.duration._
8+
import scala.concurrent.{ Promise, Await }
9+
10+
object Test {
11+
val finishedLWCR, finishedTNR, finishedEH = Promise[Boolean]
12+
val finishedLWCR1, finishedTNR1, finishedEH1 = Promise[Boolean]
13+
14+
def testLoopWithConditionReact() = {
15+
// Snippet showing composition of receives
16+
// Loop with Condition Snippet - before
17+
val myActor = actor {
18+
var c = true
19+
loopWhile(c) {
20+
react {
21+
case x: Int =>
22+
// do task
23+
println("do task")
24+
if (x == 42) {
25+
c = false
26+
finishedLWCR1.success(true)
27+
}
28+
}
29+
}
30+
}
31+
32+
myActor.start()
33+
myActor ! 1
34+
myActor ! 42
35+
36+
Await.ready(finishedLWCR1.future, 5 seconds)
37+
38+
// Loop with Condition Snippet - migrated
39+
val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor {
40+
41+
def receive = {
42+
case x: Int =>
43+
// do task
44+
println("do task")
45+
if (x == 42) {
46+
finishedLWCR.success(true)
47+
context.stop(self)
48+
}
49+
}
50+
}, "default-stashing-dispatcher"))
51+
myAkkaActor ! 1
52+
myAkkaActor ! 42
53+
}
54+
55+
def testNestedReact() = {
56+
// Snippet showing composition of receives
57+
// Loop with Condition Snippet - before
58+
val myActor = actor {
59+
var c = true
60+
loopWhile(c) {
61+
react {
62+
case x: Int =>
63+
// do task
64+
println("do task " + x)
65+
if (x == 42) {
66+
c = false
67+
} else {
68+
react {
69+
case y: String =>
70+
println("do string " + y)
71+
}
72+
}
73+
println("after react")
74+
finishedTNR1.success(true)
75+
}
76+
}
77+
}
78+
myActor.start()
79+
80+
myActor ! 1
81+
myActor ! "I am a String"
82+
myActor ! 42
83+
84+
Await.ready(finishedTNR1.future, 5 seconds)
85+
86+
// Loop with Condition Snippet - migrated
87+
val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor {
88+
89+
def receive = {
90+
case x: Int =>
91+
// do task
92+
println("do task " + x)
93+
if (x == 42) {
94+
println("after react")
95+
finishedTNR.success(true)
96+
context.stop(self)
97+
} else
98+
context.become(({
99+
case y: String =>
100+
println("do string " + y)
101+
}: Receive).andThen(x => {
102+
unstashAll()
103+
context.unbecome()
104+
}).orElse { case x => stash() })
105+
}
106+
}, "default-stashing-dispatcher"))
107+
108+
myAkkaActor ! 1
109+
myAkkaActor ! "I am a String"
110+
myAkkaActor ! 42
111+
112+
}
113+
114+
def exceptionHandling() = {
115+
// Stashing actor with act and exception handler
116+
val myActor = MigrationSystem.actorOf(Props(() => new StashingActor {
117+
118+
def receive = { case _ => println("Dummy method.") }
119+
override def act() = {
120+
loop {
121+
react {
122+
case "fail" =>
123+
throw new Exception("failed")
124+
case "work" =>
125+
println("working")
126+
case "die" =>
127+
finishedEH1.success(true)
128+
exit()
129+
}
130+
}
131+
}
132+
133+
override def exceptionHandler = {
134+
case x: Exception => println("scala got exception")
135+
}
136+
137+
}, "default-stashing-dispatcher"))
138+
139+
myActor ! "work"
140+
myActor ! "fail"
141+
myActor ! "die"
142+
143+
Await.ready(finishedEH1.future, 5 seconds)
144+
// Stashing actor in Akka style
145+
val myAkkaActor = MigrationSystem.actorOf(Props(() => new StashingActor {
146+
def receive = PFCatch({
147+
case "fail" =>
148+
throw new Exception("failed")
149+
case "work" =>
150+
println("working")
151+
case "die" =>
152+
finishedEH.success(true)
153+
context.stop(self)
154+
}, { case x: Exception => println("akka got exception") })
155+
}, "default-stashing-dispatcher"))
156+
157+
myAkkaActor ! "work"
158+
myAkkaActor ! "fail"
159+
myAkkaActor ! "die"
160+
}
161+
162+
def main(args: Array[String]) = {
163+
testLoopWithConditionReact()
164+
Await.ready(finishedLWCR.future, 5 seconds)
165+
exceptionHandling()
166+
Await.ready(finishedEH.future, 5 seconds)
167+
testNestedReact()
168+
Await.ready(finishedTNR.future, 5 seconds)
169+
}
170+
171+
}
172+
173+
// As per Jim Mcbeath's blog (http://jim-mcbeath.blogspot.com/2008/07/actor-exceptions.html)
174+
class PFCatch(f: PartialFunction[Any, Unit],
175+
handler: PartialFunction[Exception, Unit])
176+
extends PartialFunction[Any, Unit] {
177+
178+
def apply(x: Any) = {
179+
try {
180+
f(x)
181+
} catch {
182+
case e: Exception if handler.isDefinedAt(e) => handler(e)
183+
}
184+
}
185+
186+
def isDefinedAt(x: Any) = f.isDefinedAt(x)
187+
}
188+
189+
object PFCatch {
190+
def apply(f: PartialFunction[Any, Unit],
191+
handler: PartialFunction[Exception, Unit]) = new PFCatch(f, handler)
192+
}

test/files/jvm/actmig-public-methods_1.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import scala.collection.mutable.ArrayBuffer
22
import scala.actors.Actor._
33
import scala.actors._
4+
import scala.actors.migration._
45
import scala.util._
56
import java.util.concurrent.{ TimeUnit, CountDownLatch }
67
import scala.concurrent.util.Duration
7-
import scala.actors.pattern._
8+
import scala.actors.migration.pattern._
89

910
object Test {
1011
val NUMBER_OF_TESTS = 6

test/files/jvm/actmig-react-receive.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import scala.actors.MigrationSystem._
1+
import scala.actors.migration.MigrationSystem._
22
import scala.actors.Actor._
3-
import scala.actors.{ Actor, StashingActor, ActorRef, Props, MigrationSystem, PoisonPill }
3+
import scala.actors._
4+
import scala.actors.migration._
45
import java.util.concurrent.{ TimeUnit, CountDownLatch }
56
import scala.collection.mutable.ArrayBuffer
67
import scala.concurrent.util.duration._
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
received
2+
received
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import scala.actors.migration.MigrationSystem._
2+
import scala.actors.Actor._
3+
import scala.actors._
4+
import scala.actors.migration._
5+
import java.util.concurrent.{ TimeUnit, CountDownLatch }
6+
import scala.collection.mutable.ArrayBuffer
7+
import scala.concurrent.util.duration._
8+
import scala.concurrent.{ Promise, Await }
9+
10+
object Test {
11+
val finished = Promise[Boolean]
12+
13+
def testReactWithin() = {
14+
val sActor = actor {
15+
loop {
16+
reactWithin(1) {
17+
case scala.actors.TIMEOUT =>
18+
println("received")
19+
exit()
20+
case _ =>
21+
println("Should not occur.")
22+
}
23+
}
24+
}
25+
26+
val myActor = MigrationSystem.actorOf(Props(() => new StashingActor {
27+
context.setReceiveTimeout(1 millisecond)
28+
def receive = {
29+
case ReceiveTimeout =>
30+
println("received")
31+
finished.success(true)
32+
context.stop(self)
33+
case _ =>
34+
println("Should not occur.")
35+
}
36+
}, "default-stashing-dispatcher"))
37+
}
38+
39+
def main(args: Array[String]) = {
40+
testReactWithin()
41+
Await.ready(finished.future, 5 seconds)
42+
}
43+
44+
}

test/files/jvm/actmig-receive.check

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Original
2+
do before
3+
receive 1
4+
do in between
5+
receive 1
6+
do after
7+
Transformed
8+
do before
9+
receive 1
10+
do in between
11+
receive 1
12+
do after
13+
Test Loop Receive
14+
Original
15+
do before body
16+
receive 1
17+
do after receive
18+
do before body
19+
do after receive
20+
after loop
21+
Transformed
22+
do before body
23+
receive 1
24+
do after receive
25+
do before body
26+
do after receive
27+
after loop

0 commit comments

Comments
 (0)