получить метод в Akka актер - PullRequest
0 голосов
/ 20 мая 2018

У меня есть следующая реализация для метода получения в реализации актера Akka.

override def receive: Receive = {
  case SetRequest(key, value) =>{
    log.info("Received SetRequest - key:{} ,value:{}", key,value)
    map.put(key,value)
    sender() ! Status.Success
  }
  case GetRequest(key) => {
    log.info("Received GetRequest for - key:{}", key)
    val response: Option[Object] = map.get(key)
    response match {
      case Some(x) => sender() ! x
      case None => sender() ! Status.Failure(new KeyNotFoundException(key))
    }
  }
  case o => Status.Failure(new ClassNotFoundException())
}

У меня есть несколько запросов здесь.

В Actor.scala получение определяется как:

def receive: Actor.Receive

Actor.Receive это:

type Receive = scala.PartialFunction[scala.Any, scala.Unit]

Так как мой код в приемнике соответствует Actor.Receive?

Во-вторых, что это за стиль сопоставления с образцом?чтобы не получать аргументов, так что же я на самом деле пытаюсь сопоставить? Например, в коде я сопоставляю ответ, что имеет смысл, поскольку ответ вычисляется до того, как будет сопоставлен шаблон.

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Так как мой код при получении соответствует Actor.Receive?... Что это за стиль сопоставления с образцом?

В Scala case является распространенным видом частичных функций.Например:

val oneOrTwo: PartialFunction[Int, String] = {
  case 1 => "one"
  case 2 => "two"
}
// oneOrTwo: PartialFunction[Int,String] = <function1>

val reciprocal: PartialFunction[Double, Double] = { case i if i != 0 => 1 / i }
// reciprocal: PartialFunction[Double,Double] = <function1>

Следовательно, case частичные функции могут использоваться для реализации receive с подписью PartialFunction[Any, Unit].

Тип аргумента Any позволяет использоватьcase для проверки на input любого типа по вашему желанию (например, SetRequest(key, value), GetRequest(key) в вашем примере кода).

В типе возврата Unit позволяет ввести любойкод обработки сообщений (например, sender() ! Status.Success, response match {...} в вашем примере кода) и не требует возвращаемого значения.

receive, кажется, не получает аргументов, так что же я на самом деле пытаюсь сопоставить?

Ваш класс расширяется Actor, поэтому при переопределении receive,вам нужно реализовать метод, объявленный в черте Actor (см. ниже, из исходного кода Akka ), который вы уже сделали с вашей частичной функцией case.

object Actor {
  type Receive = PartialFunction[Any, Unit]
  // ...
}

trait Actor {
  def receive: Actor.Receive
  // ...
}

РасширяяActor и реализуя метод receive, Akka оснащает ваш класс всеми функциями актера, управляемого сообщениями, включая почтовый ящик , и назначает диспетчера для отправки любых сообщений, отправленных ему (например, myActor ! GetRequest(key) от другого субъекта).) как input к receive методу.

0 голосов
/ 20 мая 2018

Частичная функция взята из математики и противопоставлена ​​полной функции.Для всех входов определена общая функция:

val f = (i: Int) => i + 10

Функция f выдает действительный результат для любого входа типа Int.Однако эта частичная функция:

val g = (i: Int) => 10/i

не выполняет (ноль приведет к ошибке).

В Scala вы можете создавать такие специальные функции, например:

val h: PartialFunction[Int, Int] = {
  case i: Int if i != 0 => 10/i
}

У него есть метод isDefinedAt, который можно использовать для проверки, дает ли он действительный результат для данного ввода:

h.isDefinedAt(0) // false
h.isDefinedAt(5) // true

Вы можете вызывать частичные функции, такие как обычные функции:

h(5)

Но они также позволяют вам связывать и объединять их как обычные функции с orElse.Пример:

val x: PartialFunction[Int, String] = {
  case i: Int if i = 10 => "ten"
}

val y: PartialFunction[Int, String] = {
  case i: Int if i = 5 => five"
}

val z = y orElse x

z(10) // "ten"
z(5)  // "five"
z(0)  // MatchError

В одиночку они могут обрабатывать один случай каждый, вместе они могут обрабатывать два.

На ваш второй вопрос: receive не реализованметод в актерской черте.Он будет вызван где-то в реализации Akka с вашим сообщением.Он возвращает частичную функцию, поэтому его можно комбинировать с сообщениями Akka по умолчанию, такими как PoisonPill и т. Д.

...