Spring boot 控制Mono重复任务的执行延迟

Spring boot 控制Mono重复任务的执行延迟,spring-boot,project-reactor,reactor,Spring Boot,Project Reactor,Reactor,我正在尝试实现一种轮询机制。我希望根据某些条件增加或减少轮询间隔。我正在使用Mono.repeat with delayElements以间隔执行重复任务。但我无法找到基于某些条件修改延迟的方法 Mono.just(1). repeat(). delayElements(getPollingInterval()). takeUntil((s)-> { if(checkForEndCriteria()){

我正在尝试实现一种轮询机制。我希望根据某些条件增加或减少轮询间隔。我正在使用Mono.repeat with delayElements以间隔执行重复任务。但我无法找到基于某些条件修改延迟的方法

Mono.just(1).
    repeat().
    delayElements(getPollingInterval()).
    takeUntil((s)->
      {

          if(checkForEndCriteria()){
              log.info("Critera to end reached);
              return true;
          }
          return false;
      }).
    log().
    subscribeOn(Schedulers.boundedElastic()).
    flatMapSequential(x -> {
        List<Event> eventList = getEvents(id, lastItemTimeStamp);;
        if (!eventList.isEmpty()) {
            //Recieving events now. So want to decrease the interval.
            return Flux.fromIterable(eventList);
        } else {
        //There are no events happening .So I would like
        //to increase the delay of repeat task by 1 sec

            return Flux.just(buildHeartBeatEvent());
        }
    }).
    onErrorResume(error -> {
        log.error("Error occurred", error);
        return Flux.error(error);
    });```
Mono.just(1)。
重复()。
delayElements(getPollingInterval())。
takeUntil((s)->
{
如果(checkForEndCriteria()){
log.info(“到达终点的标准”);
返回true;
}
返回false;
}).
log()。
subscribeOn(Schedulers.boundedElastic())。
flatMapSequential(x->{
List eventList=getEvents(id,lastItemTimeStamp);;
如果(!eventList.isEmpty()){
//正在接收事件。因此希望缩短间隔。
返回通量.fromIterable(事件列表);
}否则{
//没有事件发生,所以我想
//将重复任务的延迟增加1秒
返回Flux.just(buildHeartBeatEvent());
}
}).
OneErrorResume(错误->{
log.error(“发生错误”,error);
返回通量误差(error);
});```

我用
Flux.generate()实现了这一点。

流量
.生成(接收器->{
日期日期=[下一个日期];
如果(日期!=null){
long millis=date.getTime()-System.currentTimeMillis();
下一个(百万(毫秒)的持续时间);
}
否则{
sink.complete();
}
})
.concatMap(持续时间->
单声道延迟(持续时间)
...
)
.重复();

因此,每次我们回到
generate()
时,使用
repeat()
我们可以查看一些状态,以获得下一次执行
日期

我使用
Flux.generate()
实现了这一点:

流量
.生成(接收器->{
日期日期=[下一个日期];
如果(日期!=null){
long millis=date.getTime()-System.currentTimeMillis();
下一个(百万(毫秒)的持续时间);
}
否则{
sink.complete();
}
})
.concatMap(持续时间->
单声道延迟(持续时间)
...
)
.重复();

因此,每次我们回到
generate()
时,都会使用
repeat()命令
我们可以查看一些状态以获得下一次执行
日期

而不是使用delayElements进行固定延迟,我建议您在Flux使用后立即在flatMapSequential内部使用,这样您可以根据元素轻松控制其持续时间

您还可以使用而不是repeat+takeUntil和来清理一点代码

我希望这样的东西能帮助你:

Mono.fromCallable(() -> getEvents(id, lastItemTimeStamp)).
subscribeOn(Schedulers.boundedElastic()).
flatMapMany(eventList -> Flux.fromIterable(eventList).
                              defaultIfEmpty(buildHeartBeatEvent()).
                              concatWith(Mono.delay(eventList.isEmpty() ?
                                          getEmptyListPollingInterval() : 
                                          getPollingInterval()).
                                         then().cast(Event.class))).
log().
repeat(this::checkForEndCriteria);

我建议您在Flux使用之后在flatMapSequential内部使用,这样您就可以根据元素轻松控制其持续时间,而不是使用delayElements进行固定延迟

您还可以使用而不是repeat+takeUntil和来清理一点代码

我希望这样的东西能帮助你:

Mono.fromCallable(() -> getEvents(id, lastItemTimeStamp)).
subscribeOn(Schedulers.boundedElastic()).
flatMapMany(eventList -> Flux.fromIterable(eventList).
                              defaultIfEmpty(buildHeartBeatEvent()).
                              concatWith(Mono.delay(eventList.isEmpty() ?
                                          getEmptyListPollingInterval() : 
                                          getPollingInterval()).
                                         then().cast(Event.class))).
log().
repeat(this::checkForEndCriteria);

为什么要使用reactor进行轮询?为什么要使用reactor进行轮询?感谢您的建议。我尝试了这个方法。但我面临的问题是,在这种方法中,首先生成的是创建流量,直到满足条件。在我的用例中,最终条件不是固定的。它基于用户活动。我不断轮询数据库。我正在尝试根据新事件的可用性增加轮询延迟。如果没有事件发生,则增加延迟。如果发生新事件,则将轮询间隔重置为初始值。感谢您的建议。我尝试了此方法。但我面临的问题是,在这种方法中,首先生成g在满足条件之前保持流量。在我的用例中,结束条件不是固定的。它基于用户活动。我不断轮询数据库。我试图根据新事件的可用性增加轮询延迟。如果没有事件发生,则增加延迟。如果发生新事件,则重置pol将间隔设置为初始值。