自研SmallRye Mutiny采集算子测试时AssertSubscriber无事件响应
自研Mutiny算子问题排查
核心缺陷定位
你的实现存在三个违反Mutiny算子开发规范的硬伤,直接导致第二个订阅无任何事件接收:
- 订阅状态未做隔离
你将bufferList、tempBufferList、count三个状态字段直接定义在ListCollectorUntil这个Multi算子类上,没有下沉到单次订阅专属的ListCollectorProcessor内部。Multi本身是对处理逻辑的无状态描述,所有和单次订阅绑定的缓冲、计数状态必须跟随订阅生命周期存在,放在算子类上会导致所有共享同一个Multi实例的订阅共用同一套缓冲,第一次订阅的运行残留会直接污染第二次订阅的处理逻辑。 - 背压与请求转发链路断裂
你重写了onItem方法,但没有做下游请求量校验:攒够阈值后直接无条件向下游推送onItem事件,完全不检查当前下游剩余的请求额度是否足以承载这次推送。同时没有正确绑定下游request事件与上游发射节奏,上游无法根据下游的实际需求调整发射速率,很容易形成链路堵死。 - 共享可变对象的安全隐患
你返回给下游的列表是类级别的共享tempBufferList,每次推送前都会执行clear操作,下游持有的列表引用会被后续修改清空,完全违反Mutiny的不可变事件传递规范。
第二次订阅无响应的直接原因
第一次用无界请求的普通订阅者验证时,整个链路是同步执行的:上游一口气推完全部6个条目,攒够阈值就推送,最后触发完成事件,全流程能正常跑通。
第二次使用有限请求的AssertSubscriber时,因为你没有正确把下游request(2)的请求事件传递给上游,加上缓冲状态全局共享的污染问题,整个链路在完成onSubscribe握手后就没有任何数据流动——上游等待下游发起数据请求,下游等待上游推送事件,直接形成死锁,既不会收到item回调,也不会收到完成回调。
标准化修复步骤
- 把所有订阅相关的处理状态(缓冲列表、计数阈值)从Multi算子类移到
ListCollectorProcessor内部,保证每次订阅都有独立的处理空间,不会跨订阅污染。 - 在Processor内部维护剩余请求量计数器,向下游推送事件前先校验剩余额度:额度充足时再推送并扣减对应额度,额度不足时先暂存待推送内容,等下游发起新的request事件时再触发推送;收到下游的request事件时,正确转发给上游的subscription,打通请求传递链路。
- 每次推送时生成独立的不可变列表返回,不要复用全局共享的临时缓冲,避免下游拿到的引用被后续处理修改。
- 上游触发onCompletion时,先把缓冲里未达到阈值的剩余条目按照请求额度规则推给下游,再触发完成事件,不要遗漏未推送的残留内容。
内容的提问来源于stack exchange,提问作者jzimmerli
相关产品推荐
相关产品推荐

