Fiber 的状态机

依赖拼成 epoch 字符串,字符串一变就转换;同时只允许一次转换在飞,转换尾部再比一次

Fiber 的状态机 依赖拼成 epoch 字符串,字符串一变就转换;同时只允许一次转换在飞,转换尾部再比一次 01 / 生命周期主干 02 / 出错与终止 03 / Outcomes PENDING · 依赖不齐,等 provide · 生命周期主干 · epoch = INACTIVE 01 PENDING 依赖不齐,等 provide epoch = INACTIVE LOADING · 跑插件体,收 disposer · 生命周期主干 · 在飞 02 LOADING 跑插件体,收 disposer 在飞 ACTIVE · 依赖快照已冻结 · 生命周期主干 · 服务对外可见 03 ACTIVE 依赖快照已冻结 服务对外可见 UNLOADING · disposer 逆序执行 · 生命周期主干 · 在飞 04 UNLOADING disposer 逆序执行 在飞 FAILED · 插件体抛错,退回 INACTIVE · 出错与终止 · 已记日志 FAILED 插件体抛错,退回 INACTIVE 已记日志 DISPOSED · uid 置空,不能再建 effect · 出错与终止 · 终点 DISPOSED uid 置空,不能再建 effect 终点 依赖齐了,epoch 变成 :3:7 依赖没了,或换了另一个实例 撤干净,回到等依赖 撤到一半目标又变回来 ctx.fiber.dispose() Legend 等依赖 转换在飞 对外可见 出错与终止

epoch 是什么

  • • 把每个依赖的 provider fiber 编号拼成一个字符串,比如 :3:7:12
  • • 缺任何一个依赖,整串直接置成 INACTIVE
  • • provider 换了另一个实例,编号变,字符串变,消费方跟着重启

同时只有一次转换在飞

  • • 转换途中收到新目标,只记下来,不打断正在跑的那次
  • • 转换跑完再和目标比一次,不一致就接着转
  • • 没有队列也没有锁对象,收敛靠的是比较幂等

卸载的三条保证

  • • disposer 逆序执行,后注册的先撤
  • • 单个 disposer 抛错只记日志,不中断其余
  • • 进入 DISPOSED 之后再想创建 effect 会当场抛错,而不是悄悄泄漏