Альтернативы использованию "var" для государства с актерами?
Я обнаружил, что довольно часто использую vars с аккскими актерами для поддержания состояния. Например, если я, мой актер, должен поддерживать список элементов, я мог бы сделать что-то вроде:
class ListActor extends Actor{
var xs : List[Int] = List()
def receive = {
case x : Int => xs = x :: xs
}
}
Использование изменяемой переменной, похоже, противоречит духу Scala. В качестве альтернативы я использовал это:
class ListActor2 extends Actor{
import context._
def collect_ints(accu : List[Int]) : Receive = {
case x : Int => become(collect_ints(x :: accu))
}
def receive = collect_ints(Nil)
}
Мне нравится, как это выглядит больше, но мне нужно беспокоиться о переполнении стека?
Я знаю о признаке FSM и использовал это раньше, но для некоторых ситуаций это кажется слишком большим.
Каков рекомендуемый способ поддержания простого состояния? Существуют ли другие альтернативы, о которых я не знаю?
Кроме того, это вообще плохой знак, если мне часто приходится менять переменные переменные? Я не правильно использую модель актера?
Ответы
Ответ 1
Я не вижу проблемы с var
для простого состояния в модели актера.
По дизайну Akka предотвращает повреждение или блокировку актера при одновременном доступе к переменным состояния.
Пока вы не показываете свое состояние другим потокам с использованием Будущее, например, использование var
для простого состояния не должно быть проблема.
Ответ 2
Существует два варианта метода become
: один, который толкает поведение на стек, а другой - нет. Последний является значением по умолчанию, поэтому вам не нужно беспокоиться о том, что стеки поведения становятся слишком большими. Использование become
для управления состоянием таким образом является для него вполне допустимым использованием.
Ответ 3
Akka FSM на самом деле очень компактная идиома для поддержания состояния в актерской системе, как в этом примере:
sealed trait State
case object Active extends State
class ListActor extends Actor with FSM[State,List[Int]] {
startWith(Active,List[Int]())
when(Active) {
case Event(x:Int,xs) => stay using x :: xs
}
}
Используя все альтернативы, обсуждаемые здесь, FSM берет мой голос за все, что является тенью, более сложным, чем тривиальным.