Учебное пособие по учебной программе Akka - программирование
Подтвердить что ты не робот

Учебное пособие по учебной программе Akka

Есть ли хорошие учебники/объяснения о том, как использовать шину событий в akka? Я прочитал документ Akka, но мне трудно понять, как использовать шину событий

4b9b3361

Ответ 1

Не уверен, что есть или нет хороших учебных пособий, но я могу дать вам быстрый пример возможного случая, когда использование потока событий может оказаться полезным. Однако на высоком уровне поток событий является хорошим механизмом для удовлетворения требований типа pub/sub, которые могут иметь ваше приложение. Скажем, у вас есть прецедент, когда вы обновляете баланс пользователя в своей системе. Баланс доступен часто, поэтому вы решили кэшировать его для повышения производительности. Когда баланс обновляется, вы также хотите проверить и увидеть, пересекает ли пользователь порог с их балансом, и если да, отправьте их по электронной почте. Вы не хотите, чтобы либо сброс кеша, либо проверка порога баланса были привязаны непосредственно к вызову обновления основного баланса, поскольку они могут быть тяжелыми и замедлять реакцию пользователя. Вы можете смоделировать этот набор требований следующим образом:

//Message and event classes
case class UpdateAccountBalance(userId:Long, amount:Long)
case class BalanceUpdated(userId:Long)

//Actor that performs account updates
class AccountManager extends Actor{
  val dao = new AccountManagerDao

  def receive = {
    case UpdateAccountBalance(userId, amount) =>
      val res = for(result <- dao.updateBalance(userId, amount)) yield{
        context.system.eventStream.publish(BalanceUpdated(userId))
        result                
      }

      sender ! res
  }
}

//Actor that manages a cache of account balance data
class AccountCacher extends Actor{
  val cache = new AccountCache

  override def preStart = {
    context.system.eventStream.subscribe(context.self, classOf[BalanceUpdated])
  }

  def receive = {
    case BalanceUpdated(userId) =>
      cache.remove(userId)
  }
}

//Actor that checks balance after an update to warn of low balance
class LowBalanceChecker extends Actor{
  val dao = new LowBalanceDao

  override def preStart = {
    context.system.eventStream.subscribe(context.self, classOf[BalanceUpdated])
  }

  def receive = {
    case BalanceUpdated(userId) =>
      for{
        balance <- dao.getBalance(userId)
        theshold <- dao.getBalanceThreshold(userId)
        if (balance < threshold)
      }{
        sendBalanceEmail(userId, balance)
      }
  }
}

В этом примере участники AccountCacher и LowBalanceChecker подписываются на eventStream по типу класса для события BalanceUpdated. Если это событие является событием, опубликованным в потоке, оно будет получено обоими этими экземплярами актера. Затем в AccountManager, когда обновление баланса завершается успешно, оно вызывает событие BalanceUpdated для пользователя. Когда это происходит, параллельно это сообщение доставляется в почтовые ящики как для AccountCacher, так и для LowBalanceChecker, в результате чего баланс выпадает из кеша и проверяется порог учетной записи и, возможно, отправляется электронное письмо.

Теперь вы могли бы просто направить прямые вызовы tell (!) в AccountManager для непосредственного общения с этими двумя другими участниками, но можно утверждать, что это может быть слишком тесно связано с этими двумя "побочными эффектами" обновления баланса, и что эти типы деталей не обязательно относятся к AccountManager. Если у вас есть условие, которое может привести к некоторым дополнительным вещам (проверкам, обновлениям и т.д.), Которые должны выполняться исключительно как побочные эффекты (не входящие в основной бизнес-поток), тогда поток событий может быть хорошим способом чтобы отделить событие, поднятое и кому, возможно, потребуется реагировать на это событие.

Ответ 2

Существует EventBus, который существует для каждого ActorSystem. Этот EventBus называется Event Stream и может быть получен путем вызова system.eventStream.

ActorSystem использует Event Stream для нескольких вещей, включая протоколирование, отправляя Мертвые буквы и События кластеров.

Вы также можете использовать Event Stream для своих собственных требований публикации/подписки. Например, поток событий может быть полезен во время тестирования. Подпишите Test Kit testActor для потока событий для определенных событий (например, событий регистрации), и вы можете expect их. Это может быть особенно полезно, когда вы не отправляете сообщение другому игроку, когда что-то происходит, но вы все равно должны ожидать события в своем тесте.

Обратите внимание, что поток событий работает только с одним ActorSystem. Если вы используете удаленные события, опубликованные в потоке, по умолчанию не переходите к удаленным системам (хотя вы можете добавить эту поддержку самостоятельно).

Теоретически вы можете создать отдельный EventBus, если вы не хотите использовать поток событий.

Улучшены документы для Event Bus для Akka 2.2, поэтому зайдите еще раз, когда этот билет завершен.