用途
该技能面向 Kotlin 中实现连接重连循环的代码审查与修复。核心主张是:一个没有任何限制的重试循环,在故障短暂出现时没有问题,但在故障永久存在时会变成持续发热的源头——例如凭据永远不被接受,应用仍会以每小时数千次的频率反复连接、认证、被拒、重连,导致耗电和发热,且用户难以诊断。
主要能力
资料要求为每个重连循环同时加入四道独立的限制:
- 不重复调度:调度前检查重连任务是否已处于活动状态,避免叠加两个调度器。
- 指数退避并设上限:延迟按倍数增长,并用
coerceAtMost(MAX_DELAY)封顶。 - 拒绝重试的失败类别:将认证失败、权限不足、协议版本被拒等表示凭据本身错误的关闭码或错误码显式列为终态,命中后完全停止并记录日志;其余默认按可恢复处理。
- 生命周期闸门:整个子系统由上层闸门创建和销毁,撤销凭据或关闭功能时同时拆除连接和待执行的重试,而不是让它们自行发现状态变化。
使用方式与关键陷阱
资料通过示例代码说明若干实现要点:
- 公开的
connect()函数应重置尝试计数与延迟,供用户主动发起连接;重试调度器必须调用私有的startConnection(),否则每次重试都会清零计数,上限永远无法触发。 - 延迟和尝试次数应在表示连接可用的里程碑(如握手协议的 ready/resumed 事件)处重置,而不是在 socket 打开时;否则握手中途失败的连接会不断重置退避曲线。
- 应按尝试次数而非经过时间计算预算,因为以秒计的预算会随延迟增长。
- 计数递增应放在取消操作无法跳过、且不是挂起点的位置;示例中连接路径会重新赋值保存调度任务的字段,从而取消正在运行的协程,递增之所以保留仅因它不是挂起点。
- 一旦引入终态失败,任何等待就绪的代码都需要
withTimeoutOrNull之类的超时,而非自旋等待;有界等待搭配无界重试会掩盖问题,无界等待搭配有界重试会让协程挂起至进程结束。 - 若连接只用于镜像实时活动,应在活动停止时关闭、恢复时重开,从而消除空闲期的重试面。
- 失败模式为“什么也不做”的功能必须有显式信号:丢弃时刻的警告日志含原因,或在设置项中显示可见状态,或两者兼有。
验证方法
资料给出两步核查。第一步用 grep 查找重试站点(参数为变量的 delay(...),以及 reconnect、maxRetries、attempts++、Result.retry 等词汇),再逐个文件查找 coerceAtMost、coerceIn、MAX_、maxAttempts、withTimeout,确认每个命中所在函数都有上限或超时,并检查重试路径调用的是否为公开 connect 函数。第二步分别触发四类故障并观察日志:瞬时故障(断网)应看到尝试间隔明显拉长并在上限停止增长;终态故障(提供被拒凭据)应只有一次尝试、一条说明原因的日志,之后不再出现;耗尽(断网超过上限)应停止尝试并告知用户;恢复(多次退避后恢复网络)应在下次成功连接后重置延迟,使随后的失败等待初始间隔而非上限。最后让应用空闲数分钟,任何周期性日志都说明存在未被闸门控制的重试循环。
适用场景与限制
适用于 Kotlin 连接类功能(如客户端与服务端的连接、握手协议)的重连逻辑设计与代码审查。资料为示例代码适配版,省略了拆除、日志行、关闭处理器的代码查找及其他分支;未提供该技能的安装命令、配置参数、运行平台或收费信息,这些事实暂未提供。