新闻详情

新闻详情

首页 / 资讯中心 / 详情

[DeepSeek Harness插件内核-17]将针对服务的硬依赖转换成软依赖

发布时间:2026/9/30 18:51:35来源:尧图网络
[DeepSeek Harness插件内核-17]将针对服务的硬依赖转换成软依赖
Cordis插件针对服务的消费具有一个基本的原则只有在显式注入的前提下才能消费目标服务。但是一旦完成了服务注入Cordis就会认为当前插件没有依赖服务的参与就不能正常工作所以它会将插件的生命周期和服务生命周期绑定在一起。对于插件来说只有它所有注入的依赖服务全员上线它才能上线反之如果在运行过程中有任何一个依赖服务下线自己也改不了下线的命运所以插件与服务之间就是这种硬性依赖的关系。但是很多时候插件需要保持始终处于激活的状态消费的服务也不是必需的就需要通过一些变通将针对服务的依赖变得软性一点。1. 插件只能消费显式注入的服务先注入后消费是Cordis进行服务调用的一条铁律。以如下的演示程序为例我们定义了FooService和BarService这两个实现了FoobarService接口的服务并在它们的invoke方法中输出一点指示性文字确定当前调用的服务类型。我们调用plugin方法将这两个服务注册到创建的Context中并在另一个通过调用inject方法注册的插件中试着消费这两个服务。import{Context,Service}fromdeepseek-ai/cordisinterfaceFoobarService{invoke():void}declaremoduledeepseek-ai/cordis{interfaceContext{foo:FoobarService bar:FoobarService}}classFooServiceextendsService{constructor(ctx:Context){super(ctx,foo)}invoke(){console.log(FooService.invoke() is invoked!)}}classBarServiceextendsService{constructor(ctx:Context){super(ctx,bar)}invoke(){console.log(BarService.invoke() is invoked!)}}constctxnewContext()ctx.plugin(FooService)ctx.plugin(BarService)ctx.inject([foo],ctx{for(constserviceof[()ctx.foo,()ctx.bar]){try{service().invoke();}catch(err){console.log(err)}}})输出FooService.invoke()is invoked!Error: cannot get propertybarwithout inject atanonymous(E:\dsh\deepseek-harness\explor\src\downgrade.ts:36:49)at Object.ctx(E:\dsh\deepseek-harness\explor\src\downgrade.ts:38:13)at Fiber.execute(E:\dsh\deepseek-harness\vendor\cordis\src\fiber.ts:259:28)atanonymous(E:\dsh\deepseek-harness\vendor\cordis\src\fiber.ts:366:45)at composeError(E:\dsh\deepseek-harness\vendor\cordis\src\utils.ts:272:25)at Fiber._execute(E:\dsh\deepseek-harness\vendor\cordis\src\fiber.ts:358:12)at Fiber._reload(E:\dsh\deepseek-harness\vendor\cordis\src\fiber.ts:656:20)at process.processTicksAndRejections(node:internal/process/task_queues:104:5)由于inject方法只指定了foo服务所以插件中只能调用注册的FooService。调用BarService会直接抛出异常并提示cannot get property bar without inject。2. 插件生命周期受控于依赖的服务Cordis内部会维护一个服务与插件依赖于它的插件所在Fiber的映射关系。当某个服务下线时Cordis会利用这个映射找到对用的Fiber对象并使用它让插件也下线。反之当服务重写上线后也会便利所有的映射的Fiber如果对应插件注入的服务全部处于激活的状态对应的插件会被重新拉起来。下面就是一个典型的例子import{Context,Service}fromdeepseek-ai/cordis...functiondelay(ms:number):Promisevoid{returnnewPromise(resolvesetTimeout(resolve,ms))}constctxnewContext()constfooctx.plugin(FooService)constbarctx.plugin(BarService)ctx.inject([foo,bar],ctx{console.log(plugin starts...)consttimersetInterval(()console.log(Plugin is alive.),1000)ctx.effect(()(){console.log(Plugin is disposed...)clearInterval(timer)})})ctx.plugin(asyncctx{awaitdelay(3000)foo.restart();awaitdelay(3000)bar.dispose();delay(10000)})如代码所示我们调用inject方法同时注入了foo和bar服务注册了一个插件该插件会在启动的时候输出plugin starts...,然后以1秒为间隔输出Plugin is alive.表明自己还活着。我们通过调用Context的effect方法输出Plugin is disposed...以为着这段文件会在插件下线的时候被输出。在另一个注册的插件中会在启动后3秒时调用注册FooService返回的Fiber的restart方法实施重启然后在6秒后调用FooService对应Fiber的dispose方法。整个程序运行后会生成如下的输出plugin starts... Plugin is alive. Plugin is alive. Plugin is disposed... plugin starts... Plugin is alive. Plugin is alive. Plugin is disposed...从输出结果可以看出注册插件的生命周期完全收到依赖服务的控制。任一依赖服务所在Fiber的重启都将导致插件的重启前提时所有依赖服务全员在线如果任何一个依赖服务下线后没有再起来插件将永远来起不来。3. 既能消费服务又保持插件独立的生命周期如果消费的服务并非插件必需比如我们在它上面应用了降级策略当检测到某个服务不可能时立即使用另一个服务来替换这是保持可用性的常用策略。但是如何将这套策略应用到某个插件上呢现在面临的困境在于消费服务必需注入注入就导致两者之间生命周期的依赖。其实问题很好解那就是将服务注入到之间的子插件中并利用后者来提供消费的服务和检测服务的状态。以如下的演示程序为例我们直接调用plugin方法注册了我们的插件并定义了两个FoobarService|undefined类型的primary和secondary变量分别表示主服务和后背的降级服务。插件会以1秒的间隔持续调用服务如果primary不可用就使用secondary。import{Context,Service}fromdeepseek-ai/cordis...constctxnewContext()constfooctx.plugin(FooService)ctx.plugin(BarService)ctx.plugin(ctx{letprimary:FoobarService|undefinedletsecondary:FoobarService|undefinedctx.inject([foo],ctx{primaryctx.fooreturn()primaryundefined})ctx.inject([bar],ctx{secondaryctx.barreturn()secondaryundefined})consttimersetInterval(()(primary??secondary)?.invoke(),1000)ctx.effect(()()clearInterval(timer))})awaitdelay(3000)console.log(unload FooService...)foo.dispose()awaitdelay(3000)console.log(register FooService...)ctx.plugin(FooService)插件内部两次调用inject方法基于注入的foo和bar服务注入了两个子插件。如果它们上线意味着依赖的服务必然处于激活状态此时它们分别对primary和secondary变量进行设置。由于这两个子插件没有复杂的操作foo或者bar服务就是它们唯一的依赖初始它们下线的唯一原因就是服务在可用此时只需要将primary或者secondary设置为undefined即可。在上面的演示程序中我们会在插件注册3秒后调用FooService所在Fiber的disopose方法意味着此时主服务不再可用后备的降级服务BarService会自动顶上去。程序运行的输出结果体现了这一点。再等3秒我们重新注册FoobarService插件将再次使用此服务。FooService.invoke()is invoked!FooService.invoke()is invoked!unload FooService... BarService.invoke()is invoked!BarService.invoke()is invoked!BarService.invoke()is invoked!register FooService... FooService.invoke()is invoked!FooService.invoke()is invoked!FooService.invoke()is invoked!...
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

开源利器!让DeepSeek V4 Flash在Terminal-Bench上超越Fable 5,还省11倍——TaoToken统一Key接入实战 2026/9/30 21:02:07

开源利器!让DeepSeek V4 Flash在Terminal-Bench上超越Fable 5,还省11倍——TaoToken统一Key接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
黑通道协议可自定义吗?解析工业功能安全的配置边界 2026/9/30 21:02:00

黑通道协议可自定义吗?解析工业功能安全的配置边界

1. 黑通道协议不是“黑盒”,而是工业安全通信的底层契约“可以自定义黑通道协议吗?”——这个问题在自动化工程师群里一抛出来,往往立刻引发两极反应:有人秒回“绝对不行,这是安全红线”,也有人困惑&#x…

阅读更多 →
Agent Skill: react-best-practices 实战大纲:把 React 最佳实践封装成可复用技能 2026/9/30 21:02:00

Agent Skill: react-best-practices 实战大纲:把 React 最佳实践封装成可复用技能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
2026年开源Agent工具栈:用TaoToken统一Key打通编排、记忆与MCP配置 2026/9/30 21:01:59

2026年开源Agent工具栈:用TaoToken统一Key打通编排、记忆与MCP配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
深圳芯片封装建厂手记:900平车间,先算水电账再画动线 2026/9/30 21:01:53

深圳芯片封装建厂手记:900平车间,先算水电账再画动线

深圳芯片封装产能这两年往宝安、龙华、光明几个园区集中,但十个项目里有六七个是拿到订单后才仓促找厂房。搬进去才发现变压器容量不够、货梯进不了设备木箱、空压机一开打线精度就漂——这些学费,大多交在布局规划这一步。这篇文章把几个园区产线落地攒…

阅读更多 →
VSCode配置Python环境:用TaoToken统一Key打通AI补全与调试链路 2026/9/30 21:01:46

VSCode配置Python环境:用TaoToken统一Key打通AI补全与调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉