Есть ли хорошие учебники/объяснения о том, как использовать шину событий в akka? Я прочитал документ Akka, но мне трудно понять, как использовать шину событий
Учебное пособие по учебной программе Akka
Ответ 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, поэтому зайдите еще раз, когда этот билет завершен.