Spring boot Webflux在何时重复或何时重试
我使用SpringBoot和Webflux的反应式编程。 我想重复对端点的一些调用,直到数据可用为止(将返回一些内容) 我想调用Spring boot Webflux在何时重复或何时重试,spring-boot,spring-webflux,Spring Boot,Spring Webflux,我使用SpringBoot和Webflux的反应式编程。 我想重复对端点的一些调用,直到数据可用为止(将返回一些内容) 我想调用commandControllerApi.findById,直到displayCommand返回状态==SUCCESS。如何告诉Webflux我的链的这一部分应该被调用5次,例如,因为我的数据库中的数据应该在5-10秒后出现 我认为当前代码会导致再次调用整个链,而不仅仅是调用我链的正确部分(.flatMap(commandResponse->commandControl
commandControllerApi.findById
,直到displayCommand返回状态==SUCCESS
。如何告诉Webflux我的链的这一部分应该被调用5次,例如,因为我的数据库中的数据应该在5-10秒后出现
我认为当前代码会导致再次调用整个链,而不仅仅是调用我链的正确部分(.flatMap(commandResponse->commandControllerApi.findById(commandResponse.getCommandId())
)
我的代码:
public Mono<Boolean> validateCredentials(FlowConfCredentials flowCredentials, UUID agentId) {
return securityService
.getUser()
.flatMap(
user -> {
Command command = new Command ();
command.setAgentId(agentId.toString());
command.setCommandType(COMMAND_TYPE);
command.setArguments(createArguments());
command.setCreatedBy(
user.getEmail());
return commandControllerApi.saveCommand(command);
})
// .retryWhen(Retry.fixedDelay(5, Duration.ofSeconds(5)))
.flatMap(commandResponse -> commandControllerApi.findById(commandResponse.getCommandId()))
.filter(displayCommand -> displayCommand.getStatus().equals(OaCommandStatus.SUCCESS))
.retryWhen(Retry.fixedDelay(5, Duration.ofSeconds(5)))
// .repeatWhenEmpty(
// Repeat.onlyIf(repeatContext -> true)
// .exponentialBackoff(Duration.ofSeconds(5), Duration.ofSeconds(5))
// .timeout(Duration.ofSeconds(30)))
.filter(
commandResponse ->
commandResponse.getStatus() != null
&& commandResponse.getStatus().equals(CommandStatus.SUCCESS))
.map(commandResponse -> true)
.switchIfEmpty(Mono.just(false));
}
公共Mono validateCredentials(FlowConfCredentials,UUID agentId){
返回安全服务
.getUser()
.平面图(
用户->{
Command=newcommand();
setAgentId(agentId.toString());
命令.setCommandType(命令类型);
setArguments(createArguments());
command.setCreatedBy(
user.getEmail());
返回commandControllerApi.saveCommand(命令);
})
//.retryWhen(重试.fixedDelay(5,持续时间秒(5)))
.flatMap(commandResponse->commandControllerApi.findById(commandResponse.getCommandId())
.filter(displayCommand->displayCommand.getStatus().equals(OaCommandStatus.SUCCESS))
.retryWhen(重试.fixedDelay(5,持续时间秒(5)))
//.重复(
//Repeat.onlyf(repeatContext->true)
//指数衰减(持续时间秒(5),持续时间秒(5))
//.超时(持续时间为秒(30)))
.过滤器(
命令响应->
commandResponse.getStatus()!=null
&&commandResponse.getStatus().equals(CommandStatus.SUCCESS))
.map(commandResponse->true)
.switchIfEmpty(Mono.just(false));
}
下面是调用上述metohd的方法:
public Flux<CredConfiguration> saveCredentials(
Mono<FlowConfCredentials> flowCredentials, UUID agentId) {
return flowCredentials
.filterWhen(cred -> validationService.validateCredentials(cred, agentId))
.flatMapMany(
flowConfCredentials -> {
if (condition1()) {
return caveCredentials(flowConfCredentials);
}
if (condition2()) {
return saveCredentialsForUser(flowConfCredentials.getExistingCredentials());
}
return Flux.error(new EmptyConfigurationException(CREDENTIALS_MESSAGE));
});
}
公共证书(
Mono flowCredentials,UUID代理){
返回流凭据
.filterWhen(cred->validationService.validateCredentials(cred,agentId))
flatMapMany先生(
flowConfCredentials->{
if(条件1()){
返回caveCredentials(flowConfCredentials);
}
if(条件2()){
返回saveCredentialsForUser(flowConfCredentials.getExistingCredentials());
}
返回Flux.error(新的EmptyConfiguration异常(凭据_消息));
});
}
要仅重复订阅findById返回的mono而不重新订阅上游saveCommand/getUser,请将筛选器/RepeatWheenPty移动到调用findById的flatMap中
公共Mono validateCredentials(FlowConfCredentials,UUID agentId){
返回安全服务
.getUser()
.平面图(
用户->{
命令=新命令();
setAgentId(agentId.toString());
命令.setCommandType(命令类型);
setArguments(createArguments());
command.setCreatedBy(
user.getEmail());
返回commandControllerApi.saveCommand(命令);
})
.flatMap(saveResponse->commandControllerApi.findById(saveResponse.getCommandId())
.filter(findResponse->findResponse.getStatus().equals(OaCommandStatus.SUCCESS))
.重复(
Repeat.onlyf(repeatContext->true)
指数衰减(持续时间秒(5),持续时间秒(5))
.超时(持续时间为秒(30)))
.hasElement();
}
要仅重复订阅findById返回的mono而不重新订阅上游saveCommand/getUser,请将筛选器/RepeatWheenPty移动到调用findById的flatMap中 公共Mono validateCredentials(FlowConfCredentials,UUID agentId){ 返回安全服务 .getUser() .平面图( 用户->{ 命令=新命令(); setAgentId(agentId.toString()); 命令.setCommandType(命令类型); setArguments(createArguments()); command.setCreatedBy( user.getEmail()); 返回commandControllerApi.saveCommand(命令); }) .flatMap(saveResponse->commandControllerApi.findById(saveResponse.getCommandId()) .filter(findResponse->findResponse.getStatus().equals(OaCommandStatus.SUCCESS)) .重复( Repeat.onlyf(repeatContext->true) 指数衰减(持续时间秒(5),持续时间秒(5)) .超时(持续时间为秒(30))) .hasElement(); }
Hmm不幸的是,commandControllerApi.findById只被调用一次……为了澄清,findById将只被调用一次,但它返回的mono将被重新订阅每个重复间隔。我更新了我的答案来澄清这一点。因此,确保findById返回的mono将为每个订阅执行api请求。如果没有,您可以将findById调用包装在Mono.defer中,强制为每个订阅调用findById。这取决于findById的行为。理想情况下,它会返回一个Mono,为每个订阅重新查询数据库。如果是这样,那么我的答案中的代码将按原样工作。如果findById没有为每个订阅重新查询数据库,则需要将对findById的调用包装在Mono.defer中,以强制为每个订阅调用findById方法。返回Mono/Flux的方法的作者确定