我想用Reactor设计一个处理管道,如下所示。
我有两个输入发布者orderEntries
(冷)和hotBroadcasts
(热)。我想将hotBroadcasts
发出的项聚合到(可变的)内存数据结构中,比如说HashMap
-对于orderEntries
中的每个项,我想选择一个对应的元素从该地图中,创建结果项并推送到下游订户。
hotBroadcasts
中的事件以任意顺序出现,这就是为什么我要将它们存储在内存中以便于检索。
从概念上讲,它应该像这样:
orderEntries hotBroadcasts
| |
| |
| |
\ /
----------------> <----------------
(aggregate events from hotBroadcasts)
|
|
resulting item
|
|
\/
downstream subcriber
到目前为止,我设法用ReplayProcessor
来绘制解决方案,如Kotlin伪示例所示:
val orderEntries = Flux.interval(Duration.of(1, ChronoUnit.SECONDS))
val hotBroadcasts = ReplayProcessor.create<String>(1000, false)
orderEntries.concatMap { entryId ->
// problematic filter - skims through all that ReplayProcessor has cached
hotBroadcasts.filter { broadcastId ->
"Broadcast:$entryId" == broadcastId
}
.take(1)
.map { "EntryId: $entryId, BroadcastId: $it" }
}.subscribe { LOG.info(it) }
Flux.interval(Duration.of(200, ChronoUnit.MILLIS))
.concatMap { Flux.just(it, it - 100000) }
.map { "Broadcast:$it" }
.subscribe {
hotBroadcasts.onNext(it)
}
这里的问题是,hotBroadcast
中的每个项目都会过滤掉orderEntries
的所有项目。因此,我想将它们存储在HashMap中。
有人能指出我正确的方向吗?
答案 0 :(得分:-1)
可以聚合来自两个不同发布者的消息的对象是带有2个参数的异步过程调用。可以使用io.reactivex.Single.zip(SingleSource arg1, SingleSource arg2, BiFunction func)
在rxjava中构造这样的调用,或者使用java.util.concurrent.CompletableFuture.thenCombine(CompletionStage arg2, BiFunction func)
在纯Java中构造这样的调用。
您需要一个特殊的HashMap来保存异步过程调用。首次使用给定标签访问此HashMap时,应自动创建调用。
所以一个Publicher调用
asyncProc=callMap.get(label); // asyncProc is created and stored with the label as a key
asyncProc.arg1.complete(value);
和另一个Publicher调用
asyncProc=callMap.get(label); // previously created instance returned
asyncProc.arg2.complete(value);
在两个发布者都提供了参数之后,将执行异步过程。