Skip to content

依赖与诊断

插件通过 inject 声明依赖。inject 中的一个名字有两种语义,按解析结果决定:

typescript
export const inject = ['storage', 'other-plugin'];
  • 命中作用域中登记的服务:服务依赖。实例沿作用域父链经 context.get() 读取。
  • 命中已安装的插件:插件依赖。仅约束启动顺序——被依赖方先启动、后停止——不做实例注入。
  • 都不命中:缺失依赖,插件进入"等待依赖"状态。

等待语义

缺失依赖不是错误,而是一种可恢复的状态:

  • install 时依赖未就绪:插件主体挂起(不执行),plugin list 显示 waiting 及等待的依赖清单;
  • 依赖补齐(服务经 provide / share 登记,或被依赖的插件安装):挂起的主体自动按拓扑序执行;
  • enable 时依赖未就绪:不拒绝——插件被标记为"期望启用",依赖就绪且主体执行完成后自动触发 onStart
  • 以上自动迁移全程可等待:触发依赖补齐的调用返回时,迁移已完成。

依赖判定是级联的:若插件依赖另一个等待中的插件,同样进入等待。

依赖消失与级联

依赖由就绪变为消失时(服务插件被 disable / uninstall,或被依赖的插件被卸载):

  1. 依赖它的已启用插件(含传递依赖)按依赖拓扑逆序自动停止
  2. 这些插件保留"期望启用"标记,记录为等待依赖——与用户主动禁用区分开;
  3. 依赖恢复后按拓扑正序自动重启;用户主动禁用的插件不受影响。

依赖诊断

诊断将插件分为三类:依赖就绪(进入启动序列)、等待依赖(报告等待原因,就绪后自动迁移)、循环依赖(硬错误,无法通过等待解决,排除出启动序列并给出循环路径)。

诊断发生在两个时机:

  1. 框架启动:就绪的插件按拓扑序启用,等待中的插件标记为期望启用,循环依赖的插件报错且不启动;
  2. 动态启用saukko plugin enable 每次都会重新诊断——循环依赖拒绝启用;缺失依赖按等待语义处理,响应中说明正在等待的依赖。

启动与停止顺序

框架按依赖拓扑排序启动插件:被依赖方先启动。停止按拓扑的逆序:依赖方先停止。这与作用域"先子后父"的销毁顺序一致。

服务替换与联动重启

通过 provide 覆盖根作用域中的同名服务时,框架会联动重启受影响的插件:

  1. 旧服务先停止(其生命周期钩子被摘除,不会残留);
  2. 新服务启动并就绪;
  3. 受影响集合 = 直接依赖该服务的插件 + 传递依赖这些插件的插件;
  4. 受影响插件按依赖拓扑逆序停止、正序重启:同一 Context 上重新触发 onStop / onStart,全程可等待。

未被波及的插件保持运行;当时处于禁用状态的插件不会被重启;重启失败的插件保持未启用,可手动重试。联动失败会汇总抛回发起 provide 的调用方。

Saukko.js 系列项目均使用 Apache 2.0 协议开源。