Scala актеры - худшие практики?

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

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

Ответ 1

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

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

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

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

    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 - в противном случае они могут терпеть неудачу молча, что означает, что ваша программа не делает то, что вы думаете, и, вероятно, выйдет из памяти, поскольку сообщения остаются в почтовом ящике актера.

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

Ответ 2

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

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

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