This is a problem from the chat I'm developing.
There is a main/gui object with the main method, an Actor sender, that sends the messages and a empfänger, that receives them.
The Problem is to make the empfänger use a function of the main/gui object to show the incoming messages. Because it didn't work, I simplified it, but I still didn't get the problem.
May anyone tell my why this returns nothing at the terminal?
What am I doing wrong?
import scala.actors._
object main_object {
def infoterm(msg: String) = {
println(msg)
}
def main(args: Array[String]) = {
println("hallo")
empfänger ! "foo"
}
}
object empfänger extends Actor{
var port = 50042
var name = "local"
var continuevar = true
def foo(in: String) = {
println("foo-empfänger" + in)
}
def act() {
println("ydfjskj")
test2.infoterm("tut")
println("Empfänger gestartet")
while(continuevar) {
react {
case msg:String => {
println("empfänger" + msg)
test2.infoterm(msg)
foo("empfänger" + msg)
}
}
}
}
}
Thanks for you help, but I still don't get on.
I modified like you told me but it's still not working.
Only by defining the Actor empfänger the whole program stops working, like this:
import scala.actors._
object test2 {
def infoterm(msg: String) = {
println(msg)
}
def main(args: Array[String]) = {
println("hallo")
}
}
object empfänger extends Actor{
def act() {
// test2.infoterm("tut")
// println("Empfänger gestartet")
loop {
react {
case msg:String => {
if(msg == "Stop") exit()
else {
println("empfänger" + msg)
// test2.infoterm(msg)
}
}
}
}
}
}
What am I doing wrong?
There are two ways from within an actor of looping upon receiving events:
while-receive
loop-react
You are using a mixture of the two (i.e. while-react). This simply cannot work for the following reasons:
receive
Receive blocks the current thread of execution waiting for a message to process. It can be used in a while-loop; although you should rarely use this as it ties an actor to a single thread - i.e. it is not scalable because you use 1 thread per actor.
react
Notice that the signature of the react method says that its return type is Nothing. This means that the method cannot terminate normally; it must either never return or throw an exception. In fact the latter happens; it uses exceptions as a flow-control mechanism, which only works when you use react inside loop (assuming you want to continually handle events). So your act method should look like this:
def act() {
loop {
react {
case msg: String =>
}
}
}
It's well worth a look at the actor source code to see how the exception flow control works as it is a thing of beauty.
Error Messages: Linking actors
This is something I have struggled with for the actor framework. If an actor's reactions throw an exception, the actor exits and it's quite common to have no record of this is sys-out or sys-err. It can be extremely frustrating.
I strongly recommend linking canary actors to each system actor to listen for exits as follows:
def act() {
import Actor._
self link actor {
case Exit(from, msg) => /* your logging here */
}
loop { ...
}
}
}
However, this does not work in your case (again, extremely frustrating) because your whole act method throws an exception.
You're using a while loop inside the act method. The actor works asynchronously and gets activated, when it receives a message. Use loop {} instead of while and it should work. To stop an actor you have to send it a message like 'stop and react to it in your act method with exit.
Actors are not automagically started, that would be a bad thing. You have to explicitly call the 'start' method, ie, in your main() empänger.start()
Related
I'm working with Akka classic actors (running in Play framework) and am running into a problem with the sender() method. When I build and run the code (using sbt run), I can see that sender() resolves to deadLetters actor. However, when running unit tests for that actor, sender() resolves to the correct ActorRef (even though it shouldn't).
The sender() is being invoked from within a closing future which is why I'm seeing the deadLetters when running the actual implementation. However, for some reason, I'm not seeing the deadLetters in the unit tests. Any ideas to why there is a difference of behavior between the unittests and running instance?
Some sample code to give an idea of the code structure
class MyActor extends Actor {
private def throwError() = {
// THIS IS WHERE sender() BEHAVIOR DIFFERENTIATES BETWEEN IMPLEMENTATION AND UNITTESTS
sender() ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType): Future[Done] = {
for {
Some logic here...
} yield {
if (some logic check...)
throwError()
else
Done
}
}
override def stepReceive = {
case MyMessage(args) =>
myFutureMethod(args)
}
}
Some sample code to give an idea of the unittest structure
"My failure test case" in {
val testProbe = TestProbe()
myActorImpl.tell(MyMessage(args), testProbe)
// testProbe SHOULD BE NOT BE RECEIVING A MESSAGE BASED ON THE ABOVE
// IMPLEMENTATION, BUT IT DOES.
testProbe.expectNoMessage()
}
If anyone has some tips or ideas for debugging, that would be awesome. Thanks.
Calling sender in code executed as part of a Future within an actor is non-deterministic (viz. a race condition) because your MyActor can move on to processing another message before the code in the Future executes, and if it has since then, sender will have changed, potentially to deadLetters.
In your test, if myActorImpl hasn't processed a message, sender will still point to the test probe.
Assuming you want the message to actually be sent to the sender, you need to capture it before handing it to the Future, along these lines
class MyActor extends Actor {
private def throwError(target: ActorRef) = {
// uses the captured sender, no race condition
target ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType, sender: ActorRef): Future[Done] = {
for {
Some logic here...
} yield {
if (some logic check...)
throwError(sender)
else
Done
}
}
override def stepReceive = {
case MyMessage(args) =>
myFutureMethod(args, sender) // captures the sender reference
}
}
I have an actor which creates another one:
class MyActor1 extends Actor {
val a2 = system actorOf Props(new MyActor(123))
}
The second actor must initialize (bootstrap) itself once it created and only after that it must be able to do other job.
class MyActor2(a: Int) extends Actor {
//initialized (bootstrapped) itself, potentially a long operation
//how?
val initValue = // get from a server
//handle incoming messages
def receive = {
case "job1" => // do some job but after it's initialized (bootstrapped) itself
}
}
So the very first thing MyActor2 must do is do some job of initializing itself. It might take some time because it's request to a server. Only after it finishes successfully, it must become able to handle incoming messages through receive. Before that - it must not do that.
Of course, a request to a server must be asynchronous (preferably, using Future, not async, await or other high level stuff like AsyncHttpClient). I know how to use Future, it's not a problem, though.
How do I ensure that?
p.s. My guess is that it must send a message to itself first.
You could use become method to change actor's behavior after initialization:
class MyActor2(a: Int) extends Actor {
server ! GetInitializationData
def initialize(d: InitializationData) = ???
//handle incoming messages
val initialized: Receive = {
case "job1" => // do some job but after it's initialized (bootstrapped) itself
}
def receive = {
case d # InitializationData =>
initialize(d)
context become initialized
}
}
Note that such actor will drop all messages before initialization. You'll have to preserve these messages manually, for instance using Stash:
class MyActor2(a: Int) extends Actor with Stash {
...
def receive = {
case d # InitializationData =>
initialize(d)
unstashAll()
context become initialized
case _ => stash()
}
}
If you don't want to use var for initialization you could create initialized behavior using InitializationData like this:
class MyActor2(a: Int) extends Actor {
server ! GetInitializationData
//handle incoming messages
def initialized(intValue: Int, strValue: String): Receive = {
case "job1" => // use `intValue` and `strValue` here
}
def receive = {
case InitializationData(intValue, strValue) =>
context become initialized(intValue, strValue)
}
}
I don't know wether the proposed solution is a good idea. It seems awkward to me to send a Initialization message. Actors have a lifecycle and offer some hooks. When you have a look at the API, you will discover the prestart hook.
Therefore i propose the following:
When the actor is created, its preStart hook is run, where you do your server request which returns a future.
While the future is not completed all incoming messages are stashed.
When the future completes it uses context.become to use your real/normal receive method.
After the become you unstash everything.
Here is a rough sketch of the code (bad solution, see real solution below):
class MyActor2(a: Int) extends Actor with Stash{
def preStart = {
val future = // do your necessary server request (should return a future)
future onSuccess {
context.become(normalReceive)
unstash()
}
}
def receive = initialReceive
def initialReceive = {
case _ => stash()
}
def normalReceive = {
// your normal Receive Logic
}
}
UPDATE: Improved solution according to Senias feedback
class MyActor2(a: Int) extends Actor with Stash{
def preStart = {
val future = // do your necessary server request (should return a future)
future onSuccess {
self ! InitializationDone
}
}
def receive = initialReceive
def initialReceive = {
case InitializationDone =>
context.become(normalReceive)
unstash()
case _ => stash()
}
def normalReceive = {
// your normal Receive Logic
}
case class InitializationDone
}
I'm trying to use Akka to implement a TCP server for a custom application protocol. I'm trying to follow the example given here: http://doc.akka.io/docs/akka/2.0/scala/io.html to do non-blocking IO inside a for...yield loop.
I find that when I throw an exception from inside the yield block, I can't catch it from outside the block. I think I've got a fundamental misunderstanding of how Akka or Scala is working here and I'd appreciate any tips.
I've boiled down the code to this:
import akka.actor._
import java.net.InetSocketAddress
class EchoServer(port: Int) extends Actor {
val state = IO.IterateeRef.Map.async[IO.Handle]()(context.dispatcher)
override def preStart {
IOManager(context.system) listen new InetSocketAddress(port)
}
def receive = {
case IO.NewClient(server) =>
val socket = server.accept()
state(socket) flatMap (_ => EchoServer.processRequest(socket))
case IO.Read(socket, bytes) =>
state(socket)(IO.Chunk(bytes))
case IO.Closed(socket, cause) =>
state(socket)(IO.EOF(None))
state -= socket
}
}
object EchoServer extends App
{
def processRequest(socket: IO.SocketHandle): IO.Iteratee[Unit] =
{
println( "In process request")
try {
for {
bs <- IO take 1
} yield {
println("I'll get here")
throw new Exception("Hey-o!")
println("But not here ... as expected")
}
} catch {
case e: Exception => println("And not here ... wtf?"); IO.Done() // NEVER GETS HERE
}
}
ActorSystem().actorOf(Props(new EchoServer(8080)))
}
Maybe more convenient to follow the gist here: https://gist.github.com/2296554
Can anybody explain why control does not reach my catch block in this situation?
I noticed that if I turn on debug logging in Akka, I see this message in the output:
[DEBUG] [04/03/2012 22:42:25.106] [EchoServerActorSystem-akka.actor.default-dispatcher-1] [Future] Hey-o!
So I guess the exception is getting handled by the Akka dispatcher? Can anybody explain how that's possible?
The point of non-blocking IO is of course that there is no guarantee when and where it is executed. Remember that one can write the for comprehension as
(IO take 1).map(bs => {
println("I'll get here"); throw // ...
}
What does this code do? IO take 1 returns some non-blocking Future-like thing, which is then appended a transforming function through the map method. I.e. whenever (and wherever) IO take 1 is ready, it will apply the map on the result.
All of this happens in some other thread (or using some other way of implementing the non-blocking semantics), so there is no way for the try–catch to react on any Exceptions being thrown. Nor would the bs => println(…) … method know of your exception handling. All it knows it that it should transform some input bs and have a result when it’s finished.
The lesson to be learned: When using non-blocking code avoid side-effects. Especially so, if the side effects are being used to change the flow of execution.
In order to actually catch the exception, I think you’ll have to structure it as follows (untested; see API):
def processRequest(socket: IO.SocketHandle): IO.Iteratee[Unit] =
{
println( "In process request")
(
for {
bs <- IO take 1
} yield {
println("I'll get here")
throw new Exception("Hey-o!")
println("But not here ... as expected")
}
) recover {
case e: Exception => println("And here ...?"); IO.Done()
}
}
I'm getting all in a twist trying to get this to work. New to scala and to actors so may inadvertently be making bad design decisions - please tell me if so.
The setup is this:
I have a controlling actor which contains a number of worker actors. Each worker represents a calculation that for a given input will spit out 1..n outputs. The controller has to set off each worker, collect the returned outputs, then carry on and do a bunch more stuff once this is complete. This is how I approached it using receive in the controller actor:
class WorkerActor extends Actor {
def act() {
loop {
react {
case DoJob =>
for (1 to n) sender ! Result
sender ! Done
}
}
}
}
The worker actor is simple enough - it spits out results until it's done, when it sends back a Done message.
class ControllerActor(val workers: List[WorkerActor]) extends Actor {
def act() {
workers.foreach(w => w ! DoJob)
receiveResults(workers.size)
//do a bunch of other stuff
}
def receiveResults(count: Int) {
if (count == 0) return
receive {
case Result =>
// do something with this result (that updates own mutable state)
receiveResults(count)
case Done
receiveResults(count - 1)
}
}
}
The controller actor kicks off each of the workers, then recursively calls receive until it has received a Done message for each of the workers.
This works, but I need to create lots of the controller actors, so receive is too heavyweight - I need to replace it with react.
However, when I use react, the behind-the-scenes exception kicks in once the final Done message is processed, and the controller actor's act method is short-circuited, so none of the "//do a bunch of other stuff" that comes after happens.
I can make something happen after the final Done message by using andThen { } - but I actually need to do several sets of calculations in this manner so would end up with a ridiculously nested structure of andThen { andThen { andThen } }s.
I also want to hide away this complexity in a method, which would then be moved into a separate trait, such that a controller actor with a number of lists of worker actors can just be something like this:
class ControllerActor extends Actor with CalculatingTrait {
//CalculatingTrait has performCalculations method
val listOne: List[WorkerActor]
val ListTwo: List[WorkerActor]
def act {
performCalculations(listOne)
performCalculations(listTwo)
}
}
So is there any way to stop the short-circuiting of the act method in the performCalculations method? Is there a better design approach I could be taking?
You can avoid react/receive entirely by using Akka actor's. Here's what you implementation could look like:
import akka.actor._
class WorkerActor extends Actor {
def receive = {
case DoJob =>
for (_ <- 1 to n) sender ! Result
sender ! Done
}
}
class ControllerActor(workers: List[ActorRef]) extends Actor {
private[this] var countdown = workers.size
override def preStart() {
workers.foreach(_ ! DoJob)
}
def receive = {
case Result =>
// do something with this result
case Done =>
countdown -= 1
if (countdown == 0) {
// do a bunch of other stuff
// It looks like your controllers die when the workers
// are done, so I'll do the same.
self ! PoisonPill
}
}
}
Here's how I might approach it (in way that seems to be more comments and boilerplate than actual content):
class WorkerController(val workerCriteria: List[WorkerCriteria]) {
// The actors that only _I_ interact with are probably no one else's business
// Your call, though
val workers = generateWorkers(workerCriteria)
// No need for an `act` method--no need for this to even be an actor
/* Will send `DoJob` to each actor, expecting a reply from each.
* Could also use the `!!` operator (instead of `!?`) if you wanted
* them to return futures (so WorkerController could continue doing other
* things while the results compute). The futures could then be evaluated
* with `results map (_())`, which will _then_ halt execution to wait for each
* future that isn't already computed (if any).
*/
val results = workers map (_ !? DoJob)
//do a bunch of other stuff with your results
def generateWorkers(criteria: List[WorkerCriteria]) = // Create some workers!
}
class Worker extends Actor {
def act() {
loop {
react {
case DoJob =>
// Will generate a result and send it back to the caller
reply(generateResult)
}
}
}
def generateResult = // Result?
}
EDIT: Have just been reading about Akka actors and spotted that they "guarantee message order on a per sender basis". So I updated my example such that, if the controller needed to later ask the receiver for the computed value and needed to be sure it was all complete, it could do so with a message order guarantee on only a per sender basis (the example is still scala actors, not akka).
It finally hit me, with a bit of help from #Destin's answer, that I could make it a lot simpler by separating out the part of the controller responsible for kicking off the workers from the part responsible for accepting and using the results. Single responsibility principle I suppose... Here's what I did (separating out the original controlling actor into a controlling class and a 'receiver' actor):
case class DoJob(receiever: Actor)
case object Result
case object JobComplete
case object Acknowledged
case object Done
class Worker extends Actor {
def act {
loop {
react {
case DoJob(receiver) =>
receiver ! Result
receiver ! Result
receiver !? JobComplete match {
case Acknowledged =>
sender ! Done
}
}
}
}
}
class Receiver extends Actor {
def act {
loop {
react {
case Result => println("Got result!")
case JobComplete => sender ! Acknowledged
}
}
}
}
class Controller {
val receiver = new Receiver
val workers = List(new Worker, new Worker, new Worker)
receiver.start()
workers.foreach(_.start())
workers.map(_ !! DoJob(receiver)).map(_())
println("All the jobs have been done")
}
Hi
I am using scala(2.8.1) to implement a time-consuming task handler using actor, however, I am not able to clean it up when running my unit tests, so my unit tests hung forever.
how I call the method is:
val configs = new ProjectsConfig("XXXXXXXXXXXXX")
try {
configs.start
configs.init//time consuming stuff
} finally {
configs.destory
configs.stop
}
What I plan to do is to keep the actors' reference and call exit on each on, the code snippet is like this:
init, initialize the actors and keep the reference of each actor.
destory, call exit on each actor.
stop, call exit on this actor.
however, it seems not working well. how to clean all actors in this case?
class ProjectsConfig(val url: String) extends Actor {
private var actors: List[Actor] = List()
private object Stop
def init = {
val caller = this;
for (projectConfig <- list) {
val myActor: Actor = actor {
caller ! projectConfig.instantiate
}
actors = actors ::: List(myActor)
}
}
def act() {
while (true) {
receive {
case project: Project =>
Projects.update(project)
case Stop => exit()
}
}
}
def destory {
for (actor <- actors) {
try {
actor ! exit
} catch {
case e => System.out.println(e.printStackTrace)
}
}
}
def stop() {
this ! Stop
}
1) In your specific case, I would simplify
val myActor: Actor = actor {
caller ! projectConfig.instantiate
}
to just caller ! projectConfig.instantiate. You're already making a call from the actor's sub-system, so an additional wrapping is not needed.
Besides that, though it's generally recommended to call actors from the actors' environment (spawning the call), it's not a "must" at all (and no evil will happen, if you call the actor directly in a non-actor env). In your case, wrapping the calls rather adds problems (boilerplate and inconsistencies).
2) What's actually happening in actor ! exit is actor ! Actor.exit (assuming that you have a wildcard import on Actor). This code throws an exception attempting to evaluate Actor.exit, and nothing is sent to the actor. In order to stop the actor, you must call exit on its instance. It can be done through a message-sending, that will call a protected exit:
actor{
loop{
react{
case `exit => exit('stop)
}
}
}