Scala актеры - худшие практики? - PullRequest
49 голосов
/ 11 октября 2009

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

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

Ответы [ 2 ]

55 голосов
/ 12 октября 2009
  • Избегайте !? везде, где это возможно. Вы получите заблокированную систему!

  • Всегда отправлять сообщение из потока подсистемы Actor. Если это означает создание переходного актера с помощью метода Actor.actor, пусть будет так:

    case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }

  • Добавьте обработчик"любое другое сообщение" *1021* к реакциям вашего актера. В противном случае невозможно выяснить, отправляете ли вы сообщение не тому актеру:

    case other => log.warning(this + " has received unexpected message " + other

  • Не используйте Actor.actor для своих основных актеров, вместо этого используйте подкласс Actor. Причина этого заключается в том, что только путем создания подклассов можно обеспечить разумный метод toString. Опять же, отладка актеров очень трудна, если ваши журналы завалены такими утверждениями, как:

    12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1

  • Документируйте актеров в вашей системе, явно указав, какие сообщения они получат и как именно они должны рассчитать ответ. Использование акторов приводит к преобразованию стандартной процедуры (обычно заключенной в методе), которая становится логикой, распределенной по реакциям нескольких акторов. Легко заблудиться без хорошей документации.

  • Всегда проверяйте, можете ли вы общаться со своим актером за пределами его цикла react, чтобы найти его состояние. Например, я всегда объявляю метод, который вызывается через MBean, который выглядит как следующий фрагмент кода. В противном случае может быть очень трудно определить, работает ли ваш актер, выключился, имеет большую очередь сообщений и т. Д.

.

def reportState = {
  val _this = this
  synchronized {
    val msg = "%s Received request to report state with %d items in mailbox".format(
                   _this, mailboxSize) 
    log.info(msg)
  }
  Actor.actor { _this ! ReportState }
}
  • Свяжите своих актеров вместе и используйте trapExit = true - иначе они могут молча потерпеть неудачу, означая, что ваша программа не выполняет то, о чем вы думаете, и, вероятно, выйдет из памяти, поскольку сообщения останутся в почтовом ящике актера.

  • Я думаю, что некоторые другие интересные решения в отношении дизайнерских решений, которые должны быть приняты с использованием актеров, были выделены здесь и здесь

12 голосов
/ 11 октября 2009

Я знаю, что на самом деле это не отвечает на этот вопрос, но вы должны, по крайней мере, принять во внимание тот факт, что параллелизм на основе сообщений гораздо менее подвержен ошибкам, чем параллелизм на основе потоков с общей памятью.

Полагаю, вы видели руководство для актеров в Программирование в Scala , но для записи:

  • Актеры не должны блокироваться при обработке сообщения. Там, где вы можете захотеть заблокировать, попробуйте вместо этого получить сообщение позже.
  • Используйте react {} вместо receive {}, когда это возможно.
  • Общайтесь с актерами только через сообщения.
  • Предпочитать неизменяемые сообщения.
  • Сделать сообщения автономными.
...