Могут ли актеры в Scala не обрабатывать сообщения?(пример в Программировании Scala О'Рейли) - PullRequest
3 голосов
/ 26 января 2011

Я совершенно новичок в Scala, и я пробираюсь через Программирование Scala (O'Reilly) онлайн; при этом я был удивлен результатом shapes-actor-script.scala примера в главе 1 «Вкус параллелизма» .

В частности, результат работы scala -cp . shapes-actor-script.scala должен быть:

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...

Тем не менее, примерно в 10% случаев я вообще ничего не получаю, а еще реже я получаю только первую строку в качестве вывода. Я еще недостаточно знаю о Scala, чтобы знать, нормально ли это из-за того, как работают актеры, или что-то может быть не так с моей установкой Scala (Scala 2.8.1 в Arch Linux).

Могут ли актеры не обрабатывать подобные сообщения (возможно, из-за того, как написан пример)? Или что-то еще происходит, что я мог бы здесь упустить?

Ответы [ 4 ]

5 голосов
/ 27 января 2011

Я полагаю, что Scala REPL использует System.exit (...), когда он завершает выполнение скрипта.Это остановит процесс, не дожидаясь каких-либо затяжных потоков.

Это означает, что все сообщения будут отправлены субъекту, но субъект не сможет обработать их вовремя.

Чтобы продемонстрировать, что вы можете попытаться добавить Thread.sleep (1000)для каждого из случаев в shape-actor.scala:

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)

Это, вероятно, приведет к сбою скрипта каждый раз (это происходит на моей машине).Если затем вы добавите Thread.sleep (5000) (что дает 2 секунды замедления), он должен выполняться каждый раз.

Решение состоит в том, чтобы использовать программу, которая не заканчивается в System.exit (...).

Обновление (считанные секунды):

Вы также можете настроить актера на уведомление о выходе:

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

... и затемскрипт может ждать уведомления:

ShapeDrawingActor.synchronized { ShapeDrawingActor.wait(10000) }
1 голос
/ 24 марта 2011

Извините за большую задержку с ответом на эту тему (так как я написал этот пример в книге: ^ /).Я полагаю, что реальная проблема заключается в том, что STDOUT не сбрасывается по умолчанию во всех ОС (и оболочках?), И поведение, по-видимому, отличается в зависимости от версии Scala.Этим вечером я скомпилировал и запустил код, используя 2.7.7.2.8.0 и 2.8.1 в OS X (10.6.6), Java 1.6.0_24-b07-334-10M3326 и bash.

Для 2.7.7 и 2.8.1 все выходные данные былинапечатано до завершения процесса.Для 2.8.0 появился только какой-то вывод!Когда я добавил «System.out.flush» в конец shape-actor-script.scala, весь вывод был напечатан для версии 2.8.0.

0 голосов
/ 19 марта 2011

Простое решение, добавьте это в конец shape-actor-script.scala:

Thread.sleep(1000)

Это даст актеру время напечатать все различные сообщения Shape до завершения REPL.

0 голосов
/ 27 января 2011

На самом деле, это кажется достаточно разумным.Видите, актер работает одновременно со сценарием, и ни одна из строк в сценарии не ожидает ответа.Таким образом, вполне возможно, что многие сообщения были доставлены актеру до того, как актер решит обработать любое из них.

Затем все сводится к тому, как актер должен пройти через свой почтовый ящик.Он может пройти через это как очередь.Но он также может проходить случайным образом, что обеспечивает некоторые интересные свойства.

Я предполагаю, что Scala 2.7.x, которая была версией, доступной на момент написания книги, использовала алгоритм очередей по умолчанию, а версия 2.8.1 использует случайный алгоритм.

...