scala - Lagom 中的事件标签是如何工作的?

标签 scala lagom

Lagom reference documentation显示如何标记事件:

object BlogEvent {
  val BlogEventTag = AggregateEventTag[BlogEvent]
}

sealed trait BlogEvent extends AggregateEvent[BlogEvent] {
  override def aggregateTag: AggregateEventTag[BlogEvent] =
    BlogEvent.BlogEventTag
}

sealed trait 表明可以标记父事件以使所有子事件按顺序处理:

All events with a particular tag can be consumed as a sequential, ordered stream of events.

所以我们这样做了,我们标记了我们的父事件,我们使用 slick 实现了一个 ReadSideProcessor,但它没有用。提高日志记录级别,我们看到了一条“未处理的消息”,并且我们在 SlickReadSideImpl 中发现了以下内容:

override def handle(): Flow[EventStreamElement[Event], Done, NotUsed] =
      Flow[EventStreamElement[Event]]
        .mapAsync(parallelism = 1) { element =>

          val dbAction = eventHandlers.get(element.event.getClass)
            .map { handler =>
              // apply handler if found
              handler(element)
            }
            .getOrElse {
              // fallback to empty action if no handler is found
              if (log.isDebugEnabled) log.debug("Unhandled event [{}]", element.event.getClass.getName)
              DBIO.successful(())
            }
            .flatMap { _ =>
              // whatever it happens we save the offset
              offsetDao.updateOffsetQuery(element.offset)
            }
            .map(_ => Done)

          slick.db.run(dbAction.transactionally)
        }

如果类与注册处理程序的类不完全匹配,则上面的 eventHandlers.get(element.event.getClass) 无法找到任何处理程序,例如它是一个子类(我们的案例)。

这有点令人困惑:这是期望的行为还是 JDBCReadSideImplSlickReadSideImpl 实现中的错误?

  • 如果这是所需的行为,则不应标记密封特征事件(并且可能需要在文档中更新)
  • 如果是所需的行为,则 JDBCReadSideImpl 和 SlickReadSideImpl 不能使用从类名到处理程序的映射。

最佳答案

这是按预期工作的。预计您将希望以不同方式处理具体事件类型,因此您将为每种具体类型注册一个处理程序。

用相同标签标记所有事件子类型的目的是确保同一实体上不同类型事件之间的顺序。例如,如果您有一个 BlogCreatedEvent 和一个 BlogPublishedEvent 那么您会希望确保您的处理器在发布事件之前收到创建的事件,即使它以不同的方式处理它们.

关于scala - Lagom 中的事件标签是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46877923/

相关文章:

java - Lagom lagomServiceLocatorStart 不工作 - 连接被拒绝

java - Lagom 服务使用来自 Kafka 的输入

java - 对同一项目中的多个模块使用/公开服务调用组合

java - 无法在 IntelliJ 上为我的 Maven 项目使用 lagom

generics - 以通用方式操作 Scala 集合

scala - 使用 Reader Monad 进行依赖注入(inject)

scala - 对于并行收集,聚合是否尊重顺序?

algorithm - 从至少有两个元素相等的列表中找出所有最大的子列表

android - AsyncTask.doInBackground - Android Scala 项目中抽象方法未实现错误

java - 在生产中运行 Lagom