Reactor:创建Monos到Flux的功能

时间:2018-04-20 13:53:39

标签: java project-reactor

基本上,我在Spring Boot中创建了一个队列处理器,并希望使用Reactor进行异步。我已经让一个函数需要永远循环,因为它是从队列中拉出来然后将项目标记为已处理的。

这里有效的阻止版本订阅返回Mono

while(true) {
    manager.Subscribe().block()
}

我不确定如何将其变成一个Flux我看了一个间隔,生成,创建等等,我无法在不调用block()的情况下工作。

这是我尝试过的一个例子

Flux.generate(() -> manager,
    (state, sink) -> {
        state.Subscribe().block();
        sink.next("done");
        return state;
    }));

作为Reactor的新手,我还没有找到任何关于循环和同步处理Monos而不会阻塞的事情。

以下是使用AWS Java SDK v2进行的Subscribe方法:

public Mono Subscribe() {
    return Mono.fromFuture(_client.receiveMessage(ReceiveMessageRequest.builder()
            .waitTimeSeconds(10)
            .queueUrl(_queueUrl)
            .build()))
            .filter(x -> x.messages() != null)
            .flatMap(x -> Mono.when(x.messages()
                    .stream()
                    .map(y -> {
                        _log.warn(y.body());
                        return Mono.fromFuture(_client.deleteMessage(DeleteMessageRequest.builder()
                                .queueUrl(_queueUrl)
                                .receiptHandle(y.receiptHandle())
                                .build()));
                    }).collect(Collectors.toList())));
}

基本上,我只是轮询一个SQS队列,删除这些消息然后我想再做一次。这对我来说只是探索。

谢谢!

1 个答案:

答案 0 :(得分:2)

您需要两件事:在循环中订阅的方法以及确保在每次迭代时有效调用Subscribe()方法的方法(因为需要重新创建Future)。

repeat()是一个烘焙输入操作符,一旦源完成,它将重新订阅其源。如果源错误,则重复循环停止。最简单的变体继续Long.MAX_VALUE次。

唯一的问题是,在您的情况下,Mono Subscribe()必须在每次迭代时重新创建。

为此,您可以将Subscribe()调用包装在defer中:每次新订阅发生时,它都会重新调用该方法,其中包括每次重复尝试:

Flux<Stuff> repeated = Mono
    .defer(manager::Subscribe)
    .repeat();