Skip to content

服务生命周期

服务插件经 share 提升的服务随插件的生命周期管理;服务实现 start / stop 约定时,进一步参与启动/停止序列。

share 的登记与摘除

typescript
export default async function (context: Context) {
    await context.share('database', new DatabaseService());
}
时机行为
install(主体执行)服务立即登记进根作用域,消费方沿父链可读;等待该服务的插件随即解除挂起
enable(onStart服务实现 start 约定时在此刻启动
disable(onStop服务停止(stop 约定)并从根作用域摘除,消费方读取得到 undefined
重新 enable重新登记并启动
uninstall确保摘除,不残留

start / stop 约定

typescript
class DatabaseService {
    async start() {
        await this.connect();
    }
    async stop() {
        await this.disconnect(); // 禁用、卸载与框架停止都会等待清理完成
    }
}

语义如下:

  • 插件启用时,start 随启动序列执行;插件已启用(ACTIVE)时再调用 share,立即启动并等待完成才返回;
  • stop 随停止序列执行;启动失败的服务不会收到 stop
  • 两个方法都是可选的;只实现 stop 的服务视为始终已启动,停止时一定会被调用。

依赖消失与级联

服务被摘除(服务插件被 disable / uninstall)时,框架自动级联:

  1. 依赖该服务的已启用插件(含传递依赖)按依赖拓扑逆序自动停止
  2. 这些插件记录为"等待依赖"而非用户主动禁用,plugin list 中可见等待状态;
  3. 服务恢复(服务插件重新 enable / 同名服务经 provide 登记)后,按拓扑正序自动重启

全程可等待:触发级联的 disable / uninstall 调用返回时,级联已完成;级联中单个插件的失败汇总抛回调用方。用户主动禁用的插件不会在服务恢复时被重启。

监听服务变化

作用域提供三组监听,监听器全部按登记顺序逐个等待完成:

typescript
rootScope.onAdd('database', async (name) => { /* 新增登记(provide 新增 / share 登记) */ });
rootScope.onReplace('database', async (name) => { /* provide 覆盖同名服务 */ });
rootScope.onRemove('database', async (name) => { /* share 摘除 */ });

框架自身正是用 onAdd / onRemove 实现依赖等待与级联,用 onReplace 实现联动重启。set / register 保持纯登记语义,不触发任何联动。

provide 覆盖与联动重启

框架装配路径上,通过 provide 覆盖根作用域的同名服务时:

  1. 旧服务的生命周期钩子被摘除,并等待其 stop 完成;
  2. 新服务登记并就绪;
  3. 依赖该服务的插件按依赖拓扑逆停正启(见 依赖与诊断)。

share 不允许覆盖同名登记(冲突抛错),因此服务插件之间的"替换"请走 disable/enable 或卸载/重装。

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