You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebFlux中如何仅重复指定链节点调用直至返回SUCCESS状态

解决WebFlux中仅重试特定查询步骤的问题

你现在遇到的核心问题是重试逻辑作用在了整个调用链上,导致每次重试都会重新执行saveCommand——这不仅会产生冗余操作,还可能创建重复的命令。我们只需要把重试限定在「查询命令状态」这一步就好,下面是具体的调整方案:

核心思路

  1. 命令创建(saveCommand)只需要执行一次,不需要纳入重试范围
  2. 把「根据CommandId查询状态 + 过滤SUCCESS状态」的逻辑单独封装,仅对这部分应用重试策略
  3. 确保重试只会重复查询操作,不会从头触发整个流程

修改后的代码

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);
        })
        // 重点:仅对查询状态的逻辑应用重试
        .flatMap(commandResponse -> {
            UUID commandId = commandResponse.getCommandId();
            // 封装查询+状态校验逻辑,单独添加重试
            return commandControllerApi.findById(commandId)
                .filter(displayCommand -> OaCommandStatus.SUCCESS.equals(displayCommand.getStatus()))
                .retryWhen(Retry.fixedDelay(5, Duration.ofSeconds(5))
                    // 可选:只对特定异常重试(比如命令未生成导致的404)
                    .filter(throwable -> throwable instanceof NotFoundException || 
                            (throwable instanceof ResponseStatusException && 
                            ((ResponseStatusException) throwable).getStatus() == HttpStatus.NOT_FOUND))
                );
        })
        .map(commandResponse -> true)
        .switchIfEmpty(Mono.just(false));
}

关键调整说明

  • 将retryWhen从整个链的末尾移到了flatMap内部的查询逻辑中,确保只有查询操作会被重试,前面的命令创建流程只会执行一次
  • 移除了重复的状态过滤逻辑,只保留一次状态校验即可
  • 可选的filter条件可以帮你精准控制重试触发的场景,避免因无关异常触发不必要的重试

额外优化建议

如果findById在命令未生成/状态未达标时返回的是空Mono而非抛出异常,用repeatWhenEmpty会更贴合场景:

return commandControllerApi.findById(commandId)
    .filter(displayCommand -> OaCommandStatus.SUCCESS.equals(displayCommand.getStatus()))
    .repeatWhenEmpty(Repeat.onlyIf(ctx -> true)
        .fixedDelay(5, Duration.ofSeconds(5))
        .limitRepeat(5));

这种方式直接基于「结果为空」的条件重复查询,逻辑更直观。

内容的提问来源于stack exchange,提问作者Matexon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:37:51