弹簧反应堆:如何通过按键等待多个助焊剂?

时间:2019-07-09 13:37:32

标签: java project-reactor reactor reactive-streams

从概念上讲,我有一个(无限期地)发出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 + '\'' +
                    '}';
        }
    }
}

1 个答案:

答案 0 :(得分:1)

查看合并运算符(https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#merge-org.reactivestreams.Publisher...-)的文档,看来合并不适合处理无限流:

  

请注意,合并是为与异步源或有限源一起使用而设计的。在处理尚未在专用Scheduler上发布的无限源时,您必须将该源隔离在其自己的Scheduler中,因为合并可能会在订阅另一个源之前尝试耗尽它。

我会尝试使用zip运算符(https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#zip-org.reactivestreams.Publisher-org.reactivestreams.Publisher-

Flux<Tuple2<Foo, Foo>> zipped = Flux.zip(fooFlux1, fooFlux2);

然后您的接收器可以在可用时立即消耗一双Foo。