Отправка None обратно вызывающему абоненту от актера - PullRequest
2 голосов
/ 15 сентября 2011

У меня есть простой Actor, который запрашивает базу данных с помощью ScalaQuery, которую я смоделировал для тестирования клиента, использующего его.

Я хочу, чтобы (ложный) актер ответил Some(MyObject), если идентификатор совпадает, и None в противном случае. Однако я не могу понять, как заставить это работать. Вот код, который у меня есть:

def receive = {
  case FetchSomething(someId) => {
    if (someId == 1234) self.channel ! someObject
    else self.channel ! None
  }
}

Однако вместо того, чтобы возвращать None в коде клиента, он возвращает Some(None) - что, конечно, смущает моего клиента. Как я хочу, чтобы клиент работал, примерно так:

val object = persister !! FetchSomething(1337) match {
    case myObject: Some[MyObject] => myObject
    case _ => None
}

(конечно, вышеприведенное может быть просто неверным - вместо Some это может быть Option)

Как мне этого добиться? Возможно, более конкретно, как я могу отправить None обратно через self.channel, чтобы при сопоставлении он был None, а не Some(None)?

1 Ответ

8 голосов
/ 15 сентября 2011

Ошибка в клиенте, который неправильно интерпретирует ответ, не следуя протоколу AKKA.Из документации Akka :

The !!Метод возвращает параметр [Любой], который будет равен Some (результат) при успешном возврате или None, если время ожидания истекло.

Так что, если в ответе указано None, клиент Some (None).Если ответ - Some (12), вы получите Some (Some (12)).Если клиент получает None, это не означает, что субъект ответил None, это означает, что субъект не ответил.

Это протокол AKKA , и это означает, что клиент должен обработать ответ с

case Some(answer) => process answer
case None => actor did not reply

Затем, если ваш актер ответит с помощью опции [Something], то есть ваш протокол , который является другим слоем:

case Some(answer) => /* your protocol */ answer match { 
  case Some(actualValue) => reply had actualValue
  case None => None was the reply
}
case None => actor did not reply

Который, конечно, вы также можете написать

case Some(Some(actualValue)) => 
case Some(None) => 
case None => 

Примечание, не совпадаютс x: Some[A] (не указывайте параметр типа при сопоставлении с универсальным типом).Он не работает, он не будет проверять, есть ли у вас Some[Something], но не то, что Something является A (см. Стирание типа, компилятор выдает предупреждение).Вы хотите сопоставить с case Some(x: A), который дает вам содержимое Some в x, что вы обычно хотите.Если вы на самом деле хотите Some, а не его содержимое, case s @ Some(x: A) свяжет s с экземпляром Some, x с его содержимым.Используйте _ вместо x, если вас это не интересует.

Если известно, что тип внутри параметра - A, то не упоминайте его, просто напишите case Some(x), case s: Some(_)

...