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

Smallrye Mutiny中如何为Multi添加超时控制逻辑

Smallrye Mutiny 中 Multi 超时能力实现

两类核心需求的落地方式

1. 连续时段无条目发射的空闲超时

Multi 未提供和 Uni 完全一致的ifNoItem().after()链式调用入口,但框架从早期版本就内置了相邻发射间隔检测的原生方法timeout(Duration),语义完全匹配“连续一段时间无条目即触发逻辑”的要求:

  • 方法行为:订阅流后,持续记录上一次收到上游条目的时间,只要任意两个相邻条目的发射间隔超过指定时长,就自动取消上游订阅,向下游抛出TimeoutException
  • 灵活自定义触发动作:捕获框架默认抛出的TimeoutException后,可以替换为任意业务逻辑,不需要强制中断流。

示例代码:

// 配置5分钟空闲超时规则
multi
    .timeout(Duration.ofMinutes(5))
    // 捕获超时事件,自定义处理动作
    .onFailure(TimeoutException.class)
    .recoverWithMulti(() -> {
        // 自定义逻辑参考:上报监控指标、抛出业务自定义异常、发射超时提示事件等
        Metrics.counter("multi.idle.timeout").increment();
        return Multi.createFrom().failure(new BusinessException("5分钟未收到业务数据"));
    })
// 可传入自定义调度器替换框架默认线程池
// .timeout(Duration.ofMinutes(5), customScheduledExecutor)

常用的自定义超时动作参考:

  • 收到超时后直接正常完成流,不中断业务链路:调用recoverWithCompletion()
  • 收到超时后发射一个内置的超时标记条目,后续再正常结束流
  • 触发告警、上报链路追踪埋点

2. 订阅后指定时长未完成的总流程超时

这个场景以订阅时刻为起点计算总耗时,和中间条目的发射间隔无关,只要超过指定时长还没收到流的完成信号就触发对应逻辑。由于框架内置的timeout()仅检测相邻条目间隔,该场景需要通过组合流的方式实现,核心思路是把原业务流和一个固定延时的触发流做竞速,谁先向下游传递信号就按谁的逻辑处理。

示例代码:

// 广播原Multi,支持多订阅者独立消费流
Multi<T> sharedMulti = multi.broadcast().toAllSubscribers();

// 构建30分钟固定延时的超时触发流
Multi<T> timeoutTrigger = Uni.createFrom()
    // 构建一个不主动发射条目的Uni,靠超时规则触发信号
    .<T>nothing()
    .ifNoItem().after(Duration.ofMinutes(30))
    .failWith(new BusinessException("Multi总流程超过30分钟未完成"))
    .toMulti();

// 合并原业务流和超时触发流
Multi<T> resultMulti = Multi.createBy()
    .merging()
    .streams(sharedMulti, timeoutTrigger)
    // 下游取消订阅时,自动取消两个上游的资源占用,避免泄漏
    .onCancellation().invoke(() -> log.debug("Multi流程主动终止"));

实现优势:

  • 完全复用框架已有的成熟超时实现,不需要手动管理定时任务的创建、取消逻辑
  • 超时触发时会自动取消原业务流的上游订阅,不会造成资源泄漏
  • 超时触发后的自定义逻辑和空闲超时完全一致,支持替换异常、正常完成、上报指标等动作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 01:06:06