如何使用内部排队反应流订阅者处理OnComplete消息?

时间:2015-08-29 02:11:18

标签: scala akka reactive-programming akka-stream reactive-streams

我使用Akka-Stream 1.0和简单的反应流:

  • 发布商发送N条消息
  • 订阅者使用N条消息

 override val requestStrategy = new MaxInFlightRequestStrategy(max = 20) {
    override def inFlightInternally: Int = messageBacklog.size

发布商将通过发送OnComplete消息(动态)在N个消息之后关闭流。

订阅者收到消息并立即进入canceled状态。问题是,订阅者需要一些时间来处理每个消息,这意味着我通常会有一些积压的消息 - 当用户获得canceled时无法再处理这些消息 - ActorSubscriber.scala:195中的恕我直言

处理邮件意味着我的订阅者会将工作卸载给其他人(通过Spray' ChunkedMessage发回内容)并在邮件完成后立即收到确认消息。取消Actor时,不会处理ack消息并处理待处理的消息。

建议让我完成积压工作? 我可以发明'我自己的完成标记'但这听起来很奇怪。显然,我的代码使用MaxInFlightRequestStrategy,最大值为1 - 因为需求总是只有1 - 这意味着我从来没有积压消息。

1 个答案:

答案 0 :(得分:0)

经过长时间的调试和尝试后,我想我明白了/正在发生什么 - 希望它能节省其他人的时间:

我认为我对如何实施被动用户的概念性误解失败了: 我在ActorSubscriber内部假脱机消息,并在适当的时间通过self ! SpooledMessage将这些假脱机消息释放回业务逻辑 - 这导致订阅者的计算变得疯狂:每个假脱机消息都被计算两次因为'收到'导致内部人员要求来自上游的更多消息。

通过处理actor本身内的假脱机消息来解决这个问题 - 解决了这个问题 - 允许我也正确使用OnComplete:一旦收到此消息,订阅者就不会收到任何新消息但是我处理了内部队列本身(不使用self ! ...),从而完成整个流处理。