问题
The following code works fine in Scala 2.8 but not in 2.9.0.1 (copy and paste in REPL). This will throw an exception in 2.9.0.1.
import scala.actors.Actor
import scala.actors.TIMEOUT
object A2 extends Actor {
def act = {
loop {
react {
case "hello" =>
val s = sender
reactWithin(2000){
case i:Int => s ! "hello"
case TIMEOUT => s ! "TIMEOUT"
}
case _ =>
}
}
}
}
object A1 extends Actor {
def act = {
loop {
react {
case m:String => println (A2 !? (1000, m))
case _ =>
}
}
}
}
A1.start
A2.start
A1 ! "hi"
A1 ! "hello"
If the exception is not thrown immediately, keep doing A1 ! "hi"
or A1 ! "hello"
a few times.
Is this a bug in Scala 2.9.0.1, or something wrong with the code?
[EDIT] Forgot to add the actual exception thrown.
scala> $line4.$read$$iw$$iw$A1$@6be03fce: caught java.lang.RuntimeException: unhandled timeout
java.lang.RuntimeException: unhandled timeout
at scala.sys.package$.error(package.scala:27)
at scala.actors.Actor$class.receiveWithin(Actor.scala:606)
at $line4.$read$$iw$$iw$A1$.receiveWithin(<console>:10)
at scala.actors.Channel.receiveWithin(Channel.scala:71)
at scala.actors.ActorCanReply$class.$bang$qmark(ActorCanReply.scala:32)
at $line3.$read$$iw$$iw$A2$.$bang$qmark(<console>:9)
at $line4.$read$$iw$$iw$A1$$anonfun$act$1$$anonfun$apply$1.apply(<console>:15)
at $line4.$read$$iw$$iw$A1$$anonfun$act$1$$anonfun$apply$1.apply(<console>:13)
at scala.actors.ReactorTask.run(ReactorTask.scala:31)
at scala.actors.Reactor$class.resumeReceiver(Reactor.scala:129)
at $line4.$read$$iw$$iw$A1$.scala$actors$ReplyReactor$$super$resumeReceiver(<console>:10)
at scala.actors.ReplyReactor$class.resumeReceiver(ReplyReactor.scala:68)
at $line4.$read$$iw$$iw$A1$.resumeReceiver(<console>:10)
at scala.actors.Actor$class.searchMailbox(Actor.scala:500)
at $line4.$read$$iw$$iw$A1$.searchMailbox(<console>:10)
at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Reactor.scala:117)
at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply(Reactor.scala:114)
at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply(Reactor.scala:114)
at scala.actors.ReactorTask.run(ReactorTask.scala:33)
at scala.concurrent.forkjoin.ForkJoinPool$AdaptedRunnable.exec(ForkJoinPool.java:611)
at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
EDIT2: Standalone program without REPL
package scalaapplication5
import scala.actors.Actor._
import scala.actors.Actor
import scala.actors.TIMEOUT
object Main {
A1.start
A2.start
def main(args: Array[String]): Unit = {
while (true){
A1 ! "hi"
A1 ! "hello"
Thread.sleep(1000)
}
}
}
object A2 extends Actor {
def act = loop {
react {
case "hello" =>
val s = sender
reactWithin(2000){
case i:Int => s ! "hello"
case TIMEOUT => s ! "TIMEOUT"
}
case _ =>
}
}
}
object A1 extends Actor {
def act = {
loop {
react {
case m:String => println (A2 !? (1000, m))
case _ =>
}
}
}
}
回答1:
This does appear to have been a bug in the Actor framework. Looks like you're never supposed to get a RuntimeException. See the Scala Bug Tracker for details. It was fixed July 7th 2011, and is probably awaiting release.
来源:https://stackoverflow.com/questions/6287930/is-this-a-bug-in-scala-2-9-0-1-actor-library