HoRain云--DeepSeek Harness 插件生命周期

发布时间:2026/8/20 10:47:11
HoRain云--DeepSeek Harness 插件生命周期 你有没有想过一个插件究竟从什么时刻开始「运行」又在什么时刻开始「卸载」本章节介绍 Cordis 插件模型与生命周期状态机也就是 Fiber 状态机。Fiber 是什么每个被加载的插件都拥有一个 Fiber 作用域。Fiber 可以理解成插件实例的执行单元它承载插件从声明、加载、运行到卸载的全部状态。框架通过 Fiber 知道一个插件现在处于什么阶段以及接下来可以做什么。Fiber一个插件实例在 Cordis 运行时中的状态容器。它记录该插件的生命周期状态也是卸载时清理注册的依据。Fiber 状态机Fiber 的状态按下面的顺序迁移描述一个插件从加载到卸载的完整一生。主路径是 PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED。在 LOADING 阶段如果 apply 抛出异常则进入 FAILED。状态含义发生时机PENDING已声明但所需依赖未就绪插件被加入上下文inject 的服务还没准备好LOADING依赖就绪正在执行 apply所有必需服务就绪框架调用 apply(ctx)ACTIVE插件运行中apply 正常返回注册生效FAILEDapply 抛出异常apply 执行过程中抛错加载失败UNLOADING插件正在卸载并释放资源依赖消失、被 dispose、或 HMR 触发卸载DISPOSED已完全卸载所有处置器执行完毕术语inject 是插件声明所需服务依赖的字段框架会等这些服务全部就绪后才执行 apply。依赖驱动的加载声明了 inject 的插件会等待所有必需服务就绪后再进入 LOADING。如果依赖的服务一直没出现插件就停留在 PENDING不会执行 apply。实例// 文件路径scratch-plugin/src/my-plugin.ts// 声明本插件需要 tools 与 llm 两个服务二者就绪前 apply 不会执行export const inject [tools, llm]export function apply(ctx: Context) {// 走到这里时ctx.tools 和 ctx.llm 一定已经就绪// 可以放心地注册工具、读取模型配置}这是 Cordis 用服务依赖来表达加载顺序的方式而不是手动编排启动序列。自动清理机制通过 ctx 做的任何注册在插件卸载时都会自动撤销。这是 dsh 能「自己清理」的根本原因也是热替换能安全生效的前提。注册操作卸载时的清理ctx.on(event, handler)事件监听自动移除ctx.tools.register(tool)工具注册自动移除ctx.llm.registerAdapter(names, adapter)LLM 适配器注册自动移除ctx.effect(() cleanup)返回的处置器在卸载时执行其中 ctx.effect 用来管理没有现成「注册表」可追踪的自定义资源比如网络连接。处置器的调用顺序插件卸载时处置器按注册顺序的逆序开始调用。多个异步处置器会并发执行不保证逐个完成。存在顺序依赖的清理步骤必须放进同一个 ctx.effect() 返回的处置器里由该处置器负责串行等待。例如你先后注册了 A、B 两个效果卸载时会先调用 B 的处置器再调用 A 的处置器。如果 B 的清理必须等 A 的清理完成就要把这两步写进同一个 effect。动手示例观察状态迁移官方文档用下面这个最小插件演示加载与卸载的日志。实例// 文件路径scratch-plugin/src/lifecycle-log.ts// 用 console.log 打印生命周期事件观察 apply 与 effect 的先后export function apply(ctx: Context) {// apply 被调用插件从 LOADING 进入 ACTIVEconsole.log(runoob plugin loading)// 注册一个效果返回的清理函数在卸载时执行ctx.effect(() {// 效果注册完成apply 仍在执行中console.log(runoob effect registered)// 返回 disposer插件卸载时调用return () console.log(runoob effect cleaned up)})}加载时输出runoob plugin loading runoob effect registered卸载时输出runoob effect cleaned up可以看到 apply 先执行随后执行到 effect 注册返回的处置器在卸载阶段被调用。小结自测Fiber 状态机描述了插件从声明到完全卸载的六个状态处置器按注册逆序、异步并发地清理注册。自测一下Fiber 有哪六个状态apply 抛异常时进入哪个状态为什么 ctx.on 注册的监听器不需要手动 removeListener两个存在顺序依赖的清理步骤应该怎么写才安全