Can Actors in Scala not process messages? (example in O'Reilly Programming Scala)

I am completely new to Scala, and I have worked my way through Scala Programming (O'Reilly) online; however, I was surprised by the result of the shapes-actor-script.scala example in Chapter 1, “Taste of Concurrency” .

In particular, the output of scala -cp . shapes-actor-script.scala scala -cp . shapes-actor-script.scala should be:

 Circle.draw: Circle(Point(0.0,0.0),1.0) Rectangle.draw: Rectangle(Point(0.0,0.0),2.0,5.0) Triangle.draw: Triangle(Point(0.0,0.0),Point(1.0,0.0),Point(0.0,1.0)) Error: Unknown message! 3.14159 exiting... 

About 10% of the time, I get no output, and even less often, I will only get the first line as output. I don’t know enough about Scala, but I don’t know if this is normal due to the way the actor works, or something may be wrong with my installation of Scala (Scala 2.8.1 on Arch Linux).

Can Actors not process such messages (possibly due to the way the example is written)? Or is there something else I can skip here?

+3
source share
4 answers

I believe the Scala REPL uses System.exit (...) when it exits the script. This will stop the process without waiting for any lingering streams.

This means that all messages will be sent to the actor, but the actor may not cope with them on time.

To demonstrate that you can try adding Thread.sleep (1000) to each of the cases in-actor.scala figures:

 case s: Shape => Thread.sleep(1000);s.draw() case "exit" => Thread.sleep(1000);println("exiting..."); exit case x: Any => Thread.sleep(1000);println("Error: Unknown message! " + x) 

This will probably cause the script to crash every time (on my machine). If you then add Thread.sleep (5000) (giving 2 seconds of slack), it should succeed every time.

The solution is to use a program that does not end with System.exit (...).

Refresh (seconds):

You can also configure the actor to be notified when exiting:

 case "exit" => Thread.sleep(1000);println("exiting..."); this.synchronized { this.notify }; exit 

... and then the script can wait for notification:

 ShapeDrawingActor.synchronized { ShapeDrawingActor.wait(10000) } 
+5
source

Sorry for the long delay in answering this topic (since I wrote this example in a book: ^ /). I believe the real problem is that STDOUT will not turn red by default in all OS environments (and shell?), And the behavior seems to be different depending on the version of Scala. That evening I compiled and ran the code using 2.7.7. 2.8.0 and 2.8.1 on OS X (10.6.6), Java 1.6.0_24-b07-334-10M3326 and bash.

For 2.7.7 and 2.8.1, the entire output was printed before the output of the process. For 2.8.0, there was only some way out! When I added "System.out.flush" to the end of shape-actor- script.scala, all the output was printed for 2.8.0.

+1
source

Actually, this seems reasonable enough. See, Actor is simultaneously with the script, and none of the lines in the script are waiting for an answer. Thus, it is possible that many messages were delivered to the actor before the actor decides to process them.

Then it comes to how the actor must go through his inbox. It can pass through it as a queue. But he could also go randomly through him, which gives some interesting properties.

I assume that Scala 2.7.x, which was the version available when writing the book, used the sequence algorithm by default, while version 2.8.1 uses a random algorithm.

0
source

A simple solution, add this to the end of shape-actor- script.scala:

 Thread.sleep(1000) 

This will give the actor time to print all of the various Shape messages before completing the REPL.

0
source

Source: https://habr.com/ru/post/1347864/


All Articles