从概念上讲,我有一个(无限期地)发出IP地址的源和两个处理器。
这些处理器本质上发出IO请求。 我想做的是在这些处理器完成后合并它们的结果,然后将它们传递给可以同时处理这两个结果的接收器。
我试图写一些玩具示例,但由于source
助焊剂永无止境而无法使用。
这样做的正确方法是什么?
public class Demo {
public static void main(String[] args) throws Exception {
Flux<String> source = Flux.fromIterable(Lists.newArrayList("1.1.1.1", "2.2.2.2", "3.3.3.3")).delayElements(Duration.ofMillis(500)).repeat();
ConnectableFlux<String> ipsFlux = source.publish();
Flux<Foo> fooFlux1 = Flux.from(ipsFlux)
.map(ip -> new Foo(ip, "1"));
Flux<Foo> fooFlux2 = Flux.from(ipsFlux)
.map(ip -> new Foo(ip, "2"));
Flux.merge(fooFlux1, fooFlux2)
.groupBy(Foo::getId, Function.identity())
.subscribe(flux -> flux.collectMap(foo -> foo.type).subscribe(System.out::println));
ipsFlux.connect();
Thread.currentThread().join();
}
static class Foo {
String id;
String type;
public Foo(String id, String type) {
this.id = id;
this.type = type;
}
public String getId() {
return id;
}
@Override
public String toString() {
return "Foo{" +
"id='" + id + '\'' +
", value='" + type + '\'' +
'}';
}
}
}
答案 0 :(得分:1)
查看合并运算符(https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#merge-org.reactivestreams.Publisher...-)的文档,看来合并不适合处理无限流:
请注意,合并是为与异步源或有限源一起使用而设计的。在处理尚未在专用Scheduler上发布的无限源时,您必须将该源隔离在其自己的Scheduler中,因为合并可能会在订阅另一个源之前尝试耗尽它。
Flux<Tuple2<Foo, Foo>> zipped = Flux.zip(fooFlux1, fooFlux2);
然后您的接收器可以在可用时立即消耗一双Foo。