尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
[DeepSeek Harness插件内核-13]ReistryServices是如何注册插件的?
Cordis 中万物皆插件但是插件的定义简单至极用来调用插件执行和管理器周期的Fiber才是核心所在。在通过DeepSeek Harness插件内核-10Fiber是如何管理插件生命周期的 完成了针对插件和Fiber的深度介绍之后我们介绍一下用来注册插件的RegistryService服务。1. 注册的插件如何存储通过前面系列文章的介绍我们知道通过ReigstryService的plugin方法可以注册如下三种类型的插件并会调用resolve方法将她们统一转换成一个函数。exportclassRegistryService{resolve(plugin:Plugin):Function|undefined{try{if(typeofpluginfunction)returnpluginif(isApplicable(plugin))returnplugin.apply}catch{}}}exportnamespacePlugin{exportinterfaceBaseTany{name?:stringConfig?:StandardSchemaV1any,Tinject?:Inject provide?:string|string[]intercept?:Dictboolean}exportinterfaceFunctionTanyextendsBaseT{(ctx:Context,config:T):any}exportinterfaceConstructorTanyextendsBaseT{new(ctx:Context,config:T):any}exportinterfaceObjectTanyextendsBaseT{apply(ctx:Context,config:T):any}}exporttypeInjectMDict(keyofM)[]|{[KinkeyofM]?:M[K]}针对同一个插件函数表示最终通过resolve方法生成的Function的第一次注册将会伴随着Plugin.Runtime的创建后者的callback属性返回的就是此函数。除此之外如果注册是指定了插件名称它会体现在name属性上另一个Config属性返回的StandardSchemaV1可以用来检验提供的插件配置的结构。注册的每个插件实例都会对应一个Fiber对象针对当前函数注册的实例会被存储在fiber属性返回的DisposableListFiber列表中。exportnamespacePlugin{exportinterfaceRuntime{name?:stringfibers:DisposableListFibercallback:globalThis.FunctionConfig?:StandardSchemaV1}}exportclassRegistryService{private_counter0private_internalnewMapFunction,Plugin.Runtime()constructor(publicctx:Context){defineProperty(this,symbols.tracker,{property:ctx,noShadow:true,})}}RegistryService会使用_internal属性返回的字典来存储注册的插件该字典的Key和Value分别是插件函数和对应的Runtime对象。除此之外它还有一个通过_counter表示的插件注册计数器。该计数器将会作为注册插件对应Fiber的uid对于每一次插件注册该计数器都会自增。上面的代码一并给出了RegistryService的构造函数的定义通过为symbols.tracker属性设置一个Tracker对象并将其property属性设置为ctx意味着当前的Context将会绑定到它的公共属性ctx上具体原理可以参考我的文章DeepSeek Harness插件内核-07:Context全面解析。Tacker的noShadow设置为True意味着在调用其方法的时候提供的Context不会附加影子上下文。2. 两种插件注册方式插件的常规注册指的是调用Plugin方法来注册插件。从如下的代码可知调用该方法除了必须提供三种形式之一的插件之外我们还可以提供插件的配置以及一个用来获取或者构建当前调用堆栈的的函数默认提供的是如下定义的buildOuterStack函数。exportclassRegistryService{plugin(plugin:Plugin,config?:any,getOuterStackbuildOuterStack()){constcallbackthis.resolve(plugin)if(!callback)thrownewError(invalid plugin, expect function or object with an apply method, received typeofplugin)this.ctx.fiber.assertActive()letruntimethis._internal.get(callback)if(!runtime){letnameplugin.nameif(nameapply)nameundefinedruntime{name,callback,fibers:newDisposableList(),Config:plugin.Config}this._internal.set(callback,runtime)}constfibernewFiber(this.ctx,config,Inject.resolve(plugin.inject),runtime,getOuterStack)constwrappedObject.create(fiber)asFiberPromiseLikeFiberwrapped.then(onFulfilled,onRejected){returnfiber.await().then(onFulfilled,onRejected)}returnwrapped}}exportfunctionbuildOuterStack(offset0){constouterErrornewError()return()outerError.stack!.split(\n).slice(3offset)}在将提供的原始插件通过resolve方法转换成通过的插件函数并确认当前Fiber为激活状态之后plugin方法会试着利用该返回从_internal字典中提取对应的Runtime对象如果不存在就创建一个。接下来针对Fiber的创建是plugin方法的核心操作调用Fiber构造函数传入的参数包括当前Context;提供的可选配置注入服务这里为空创建的Runtime构建或者获取当前调用堆栈的函数我们在DeepSeek Harness插件内核-10Fiber是如何管理插件生命周期的逐行分析过Fiber构造函数的实现。如果满足插件执行的要求即插件对象的inject属性提供的注入服务全部就绪创建的Fiber会提供它绑定的Context和配置执行插件函数。否则会进入Fiber构建的状态机流转循环。这最后四行代码的核心意图非常巧妙它是一种经典的双态Dual-state代理设计模式。它的核心目的是让 plugin方法的返回值既是一个可以立即同步使用的Fiber实例同步态又是一个可以通过await或.then()异步等待插件加载就绪的 Promise 对象异步态。DeepSeek Harness插件内核-12这算Cordis一个大BUG吗?(续) 我们介绍了Cordis针对先注入声明后调用消费的依赖注入策略如果调用plugin方法并希望同时提供依赖服务的注入声明注册的插件只能采用对象形式。如果希望采用最简单的函数形式可以调用如下这个inject方法。exportclassRegistryService{inject(inject:Inject,callback:Plugin.Functionvoid){returnthis.plugin({inject,apply:callback,name:callback.name})}}exporttypeInjectMDict(keyofM)[]|{[KinkeyofM]?:M[K]}inject方法提供的服务注入声明可以是以来服务名称列表也可以是包含服务配置的字典。方法内部会插件回调函数和提供的服务注入声明转换成对象形式的产检最终还是调用plugin方法实施注册。3. 其他方法除了最为核心的用来注册插件的plugin和inject方法,以及将三种形式的插件统一转换成函数的resolve方法外RegistryService还提供了一系列额外的方法这些方法基本是围绕针对_counter和_internal这两个字段的读写实现。exportclassRegistryService{private_counter0private_internalnewMapFunction,Plugin.Runtime()getcounter(){returnthis._counter}getsize(){returnthis._internal.size}get(plugin:Plugin){constkeythis.resolve(plugin)returnkeythis._internal.get(key)}has(plugin:Plugin){constkeythis.resolve(plugin)return!!keythis._internal.has(key)}delete(plugin:Plugin){constkeythis.resolve(plugin)construntimekeythis._internal.get(key)if(!runtime)returnthis._internal.delete(key)for(constfiberofruntime.fibers){fiber.dispose()}returnruntime}keys(){returnthis._internal.keys()}values(){returnthis._internal.values()}entries(){returnthis._internal.entries()}forEach(callback:(value:Plugin.Runtime,key:Function)void){returnthis._internal.forEach(callback)}counter 在注册插件之前被调用利用自证的计数器作为插件绑定Fiber对象的uidsize回去当前注册插件函数非插件实例的数量get 根据指定的插件提取对应的Runtimehas确定指定的插件是否被注册delete借助指定插件所有实例的注册它不仅仅是将对应的Runtime从_internal字典中移除还会调用每个插件实例对应Fiber对象的dispose方法将销毁同时实施存续期间收集的清理工作keys/values/entries 针对_internal的Key、Value和KV的迭代forEach 针对每个Runtime和插件函数执行指定的回调。
RELATED

相关推荐

基于Cyclone III FPGA与USB3.0的DDR2高速数据采集系统设计与调试

基于Cyclone III FPGA与USB3.0的DDR2高速数据采集系统设计与调试

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

📅 2026/10/11 1:14:35
2026毕业季开题攻略:开题报告总卡壳?从选题到格式排版的实用工具协同测评

2026毕业季开题攻略:开题报告总卡壳?从选题到格式排版的实用工具协同测评

进入2026年论文开题季,在开题准备过程中,大家常遇到的难点集中在:选题方向不够聚焦、文献综述缺乏系统梳理、提纲层级逻辑不清、段落衔接生硬、图表编号与交叉引用繁琐、参考文献格式不规范以及目录页码反复排版崩溃等。面对这些实际问题&…

📅 2026/10/6 3:07:05
从迷茫到掌控:我用“七年一辈子”思维完成大二逆袭复盘

从迷茫到掌控:我用“七年一辈子”思维完成大二逆袭复盘

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

📅 2026/10/5 11:58:40
MORE NEWS

更多资讯

📰

STAC规范从零落地:空间元数据编目与时空检索实践

做地理数据这一行的人,几乎都经历过同一个阶段:硬盘里躺着几百上千个影像文件夹,每个文件夹里塞着 tif、xml、txt、prj,想知道"去年三月到六月、覆盖某片山区的影像有哪些",只能靠文件夹命名规则加一个手维护…

📰

网络勒索攻击防御实战指南与防护策略

1. 项目概述:一本关于网络勒索攻击的实战指南《揭秘网络勒索攻击:从基础知识到应对策略全解析》这本书的出版恰逢其时。作为网络安全从业者,我亲眼目睹了过去五年间勒索软件攻击数量增长了近300%。这本书的价值在于它没有停留在理论层面&…

📰

自建本地AI语音工作台VoiceStudio:从选型到调优的完整实战

去年我们团队在给一批短视频账号做批量配音时,被市面上的在线语音合成API折磨得够呛——单条内容动辄几毛钱成本、高峰期延迟飘到一两秒、客户想要的声音风格API里根本没有。那时候我就意识到,只当一个“API调用者”永远触及不到这个领域的天花板&#x…

📰

Dapper ORM实现高效SQL CRUD操作指南

1. Dapper与原生SQL CRUD操作概述在.NET生态系统中,Dapper作为一款轻量级ORM工具,以其卓越的性能和简洁的API设计赢得了开发者的青睐。与Entity Framework等全功能ORM不同,Dapper采用"微ORM"的架构理念,它不尝试抽象掉S…

📰

智能系统架构的演进与实践:从静态设计到动态进化

1. 系统架构的智能化演进背景十年前我们设计系统时,画完UML图、定好接口规范就能交付一套"完成态"的架构。如今在AI驱动的业务场景中,这种静态设计模式正在被彻底颠覆。上周我负责的电商推荐系统刚完成第37次架构自动调整——基于实时流量特征…

📰

DeepSeek Harness桌面端架构解析:Electron+Node+Python技术栈深度实践

1. 项目概述:这不是“又一个桌面端”,而是本地AI工作流的临界点突破最近在技术圈刷到一条消息:“DeepSeek Harness 出了桌面端?”——标题里那个“扒了一遍”的动词,瞬间勾住了我。不是因为好奇它长什么样,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬