Scala актеры - худшие практики?
Я чувствую себя немного неуверенно в использовании актеров в Scala. Я прочитал документацию о том, как делать что-то, но я думаю, что мне также понадобятся некоторые правила НЕ для того, чтобы свободно их использовать. Я думаю, что я боюсь, что я буду использовать их неправильно, и я даже не замечу этого.
Можете ли вы придумать что-то такое, что, если его применить, приведет к потере преимуществ, которые приносят актеры Scala, или даже к ошибочным результатам?
2 ответа
избежать
!?
где это возможно. Вы получите заблокированную систему!Всегда отправляйте сообщение из потока Actor-подсистемы. Если это означает создание переходного актера через
Actor.actor
метод то пусть будет такcase ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
Добавьте обработчик "любого другого сообщения" к реакциям вашего актера. В противном случае невозможно выяснить, отправляете ли вы сообщение не тому актеру:
case other => log.warning(this + " has received unexpected message " + other
Не использовать
Actor.actor
для ваших основных актеров, sublcassActor
вместо. Причина этого заключается в том, что только путем подкласса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
- иначе они могут молча потерпеть неудачу, означая, что ваша программа не выполняет то, о чем вы думаете, и, вероятно, не хватит памяти, поскольку сообщения остаются в почтовом ящике актера.Я думаю, что здесь и здесь были выделены некоторые другие интересные решения в отношении дизайнерских решений, принимаемых с использованием актеров.
Я знаю, что на самом деле это не отвечает на этот вопрос, но вы должны, по крайней мере, принять во внимание тот факт, что параллелизм на основе сообщений гораздо менее подвержен странным ошибкам, чем параллелизм на основе потоков с общей памятью.
Я предполагаю, что вы видели руководство для актеров в Программировании в Scala, но для записи:
- Актеры не должны блокировать во время обработки сообщения. Там, где вы можете захотеть заблокировать, попробуйте организовать сообщение позже.
- использование
react {}
скорее, чемreceive {}
когда возможно. - Общайтесь с актерами только через сообщения.
- Предпочитаю неизменные сообщения.
- Сделайте сообщения автономными.