仅保留最后n个元素的Reactor EmitterProcessor?

时间:2019-01-28 15:17:40

标签: java project-reactor eventemitter

我如何创建仅保留 latest n个元素的EmitterProcessor,以便即使没有订阅者也可以使用?

此刻,我创建了一个这样的处理器:

EmitterProcessor<Integer> processor = EmitterProcessor.create();

并且外部系统全天随机提供温度更新。在该系统的回调中,我这样做:

void tempConsumer(int temp) {
    processor.onNext(temp);
}

但是,一旦添加onNext(...)个元素,processor.getBufferSize()就会阻塞。

在这种情况下,如何创建丢弃最旧元素而不是阻塞的处理器?

reactor-core #763中似乎对此有所涵盖。 SimonBaslé首先讨论了proposed changeEmitterProcessor,这样,当“在没有订阅者的情况下发送数据[并且]队列中包含bufferSize个元素时,最旧的元素将被丢弃,而{{1 }}已入队。”但是,在接下来的评论中,他说:“我们不会继续上述建议的更改。我们建议您使用onNext而不是直接使用sink()。即,使用{ onNext内的{1}}回调可以执行与请求一样多的onRequest。”

但是,如果我理解正确,这仅涉及可以按需计算新元素的情况,例如像这样:

sink()

但是在我的情况下,我无法根据需要生成最新的n个温度读数。当然,我可以维护自己的最新读数的外部缓冲区,然后从sink.next(...)中读取该缓冲区,但我假设Reactor可以为我做到这一点?

我认为这个问题是重复的-但是我的Google foo在这里失败了。


理查德·科尔卡库(Ricard Kollcaku)的​​answer应该使用ReplayProcessor似乎是做事的正确方法。这是我写的另一个示例,目的是让我清楚地知道如何使用它:

FluxSink<Integer> sink = processor.sink();
Random random = new Random();

sink.onRequest(n -> random.nextInt()); // Generate next n requested elements.

我还发现this section中的Hands-On Reactive Programming with Reactor对解释事物很有用。

1 个答案:

答案 0 :(得分:2)

您必须使用ReplayProcessor这样的示例:

 ReplayProcessor<Integer> directProcessor = ReplayProcessor.cacheLast();

    Flux.range(1, 10)
            .map(integer -> {
                directProcessor.onNext(integer);
                return integer;
            }).doOnComplete(() -> {
        directProcessor.subscribe(System.out::println);
        directProcessor.subscribe(System.out::println);
    })
            .subscribe();