【发布时间】:2020-07-24 15:03:50
【问题描述】:
我有一个监听事件流的应用程序。这些事件往往成块出现:10 到 20 个在同一秒内发生,它们之间有几分钟甚至几小时的沉默。这些事件被处理并产生一个聚合状态,并且这个更新的状态被进一步发送到下游。
在伪代码中,它看起来像这样:
kafkaSource()
.mapAsync(1)((entityId, event) => entityProcessor(entityId).process(event)) // yields entityState
.mapAsync(1)(entityState => submitStateToExternalService(entityState))
.runWith(kafkaCommitterSink)
问题是下游 submitStateToExternalService 每秒更新 10-20 个状态是没有用的 - 只发出最后一个状态并只处理那个状态会更有效。
考虑到这一点,我开始研究是否不能在处理后立即不发出状态,而是等待一段时间看看是否有更多事件进入。
在某种程度上,它类似于conflate,但它会在下游停止背压时立即发出元素,而且我的处理速度实际上足以跟上进来的事件,所以我不能依赖背压.
我遇到了groupedWithin,但只要窗口结束(或达到最大元素数),它就会发出元素。理想情况下,我想要的是一个时间窗口,其中在向下游发射之前的等待时间由组中的每个新元素重置。
在我自己实现一些东西来做这件事之前,我想确保我没有忽略 akka-streams 中已经存在的做这件事的方法,因为这似乎是一个相当普遍的事情。
【问题讨论】:
标签: scala akka akka-stream