Reputation: 45
I tried to implement a timer based on Scala's actors API with, the current Thread actor (Actor.self) as the timer and an anonymous Actor which does the work that needs to be completed in time. I have the following Scala program
import scala.actors.Actor.self
import scala.actors.TIMEOUT
object Main {
def main(args: Array[String]): Unit = {
val thiz = self
actor {
// do heavy work here
thiz ! "finish"
}
self.reactWithin(1000) {
case "finish" => println("complete")
case TIMEOUT => println("timeout")
}
}
}
When I run the program, I received
Exception in thread "main" scala.actors.SuspendActorControl
scala.actors.ActorProxy@1d99a4d: caught java.lang.InterruptedException
Please show me the way to overcome the problem.
Upvotes: 4
Views: 688
Reputation: 67280
You have two types of control passing with scala-actors, thread-blocking or thread-suspension. the latter means a control exception is thrown (the thread is made available again to the thread pool manager), and the actor body re-executed when a message comes into its mailbox. See the actors tutorial for more details, esp. section "Make it Thread-less!".
The receiveWithin
method uses the thread-blocking, and the reactWithin
the suspension. The problem you have here is that there is no outer managing actor that catches the exception. This only works within a "proper" actor, not with the proxy created for the main thread. So if you want to wait on the main thread outside an explicit actor, you need to use thread blocking / receiveWithin
:
self.receiveWithin(1000) { ... }
Upvotes: 6