Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Webflux在何时重复或何时重试_Spring Boot_Spring Webflux - Fatal编程技术网

Spring boot 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

我使用SpringBoot和Webflux的反应式编程。 我想重复对端点的一些调用,直到数据可用为止(将返回一些内容)

我想调用
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的方法的作者确定