DeepSeek Harness 的基石:从源码理解 Cordis
DeepSeek Harness çåºç³ï¼ä»æºç çè§£ Cordis
ç¥å¥å°æ±¤å 2026-08-18 0 é 读8åéCordis æ¯ä¸ä¸ªé¢å TypeScript / Node.js åºç¨çå æ¡æ¶ãå®ä¸è§å®ä½ å¿ é¡»åæºå¨äººãWeb æå¡è¿æ¯å½ä»¤è¡å·¥å ·ï¼å®æä¾çæ¯æ´åºå±çè½åï¼è®©æä»¶ãæå¡ãäºä»¶ãé ç½®ä¸èµæºçå½å¨æè½å¤å®å ¨å°ç»åèµ·æ¥ã
妿åªçä½¿ç¨æ¹å¼ï¼Cordis å¾ç®åï¼
constctx =newContext()
awaitctx.plugin(plugin)
ctx.emit('event-name')
ä½å®çæ£çä»·å¼ä¸å¨è¿å è¡ APIï¼èå¨å ¶è¿è¡æºå¶ï¼æä»¶çä¾èµå¦ä½çå¾ ãæå¡å¦ä½æä½ç¨åè§£æãèµæºå¦ä½èªå¨æ¸ çï¼ä»¥åæå¡åååä¾èµæä»¶ä¸ºä»ä¹è½å¤èªå¨éè½½ã
çè§£ Cordisï¼å¯ä»¥ä»å个对象å¼å§ï¼ContextãFiberãReflectåRegistryã
Contextï¼åºç¨ä¸ä¸æï¼
ââ Registryï¼ç®¡çæä»¶
ââ Reflectï¼ç®¡çæå¡
ââ Eventsï¼ç®¡çäºä»¶
ââ Fiberï¼ç®¡ç䏿¬¡æä»¶è¿è¡ççå½å¨æ
Contextï¼çèµ·æ¥æ¯å¯¹è±¡ï¼å®é 䏿¯æå¡å ¥å£
Cordis 䏿叏è§çå鿝ctxï¼
ctx.database
ctx.logger
ctx.on('message', callback)
表é¢ä¸ï¼å®åä¸ä¸ªæ®é JavaScript 对象ï¼ä½å¨å®ç°ä¸ï¼Contextä¼è¢«Proxyå
è£
ãå æ¤è®¿é®ctx.databaseæ¶ï¼æ¡æ¶å¹¶ä¸åªæ¯è¯»åä¸ä¸ªå¯¹è±¡å段ï¼èä¼è¿è¡ä¸æ¬¡æå¡è§£æã
å¤§è´æµç¨å¦ä¸ï¼
读å ctx.database
â
Context æ¯å¦æ¬èº«æ¥æè¯¥å±æ§ï¼
ââ æ¯ï¼ç´æ¥è¿å
ââ å¦ï¼å° database è§ä¸ºæå¡å
â
å¨å½åæä»¶ Fiber 䏿¥æ¾
â
æ²¿ç¶ Fiber å䏿¥æ¾
â
æ¾å°å¯¹åºä½ç¨åå
çæå¡åè¿å
è¿ä½¿å¾æä»¶ä¸å¿
å
³å¿æå¡å®ä¾å¨åªéå建ï¼ä¹ä¸éè¦ä»å
¶ä»æä»¶æå¨å¯¼å
¥ä¸ä¸ªå
¨å±åä¾ãå®åªè¦ä½¿ç¨ctx.databaseï¼Cordis å°±ä¼å¨å½åä¸ä¸æä¸å¯»æ¾æ£ç¡®çæå¡ã
è¿ä¹æ¯ Cordis è½æ¯æå¤ä¸ªæå¡å®ä¾ãå¤ä¸ªç§æ·æå¤ä¸ªæºå¨äººå®ä¾çåºç¡ã
æºç å
¥å£ï¼packages/core/src/context.tså¨å建Contextæ¶å»ºç« Proxyï¼packages/core/src/reflect.tsè´è´£å¤çæå¡å±æ§ç读åä¸åå
¥ã
Fiberï¼ä¸æ¬¡æä»¶å®è£ ï¼å°±æ¯ä¸ä¸ªå¯ç®¡ççè¿è¡åå
è°ç¨ï¼
constfiber =awaitctx.plugin(plugin)
Cordis ä¸ä¼ç®åæ§è¡plugin(ctx)ç¶åç»æãå®ä¼å建ä¸ä¸ªFiberã
Fiber å¯ä»¥ç解为âè¿ä¸ªæä»¶çè¿è¡å®ä¾âï¼å®ä¿åäºï¼
- æä»¶æ¬èº«åå ¶é ç½®
- ç¶çº§ Context
- 声æçä¾èµæå¡
- æä»¶å½åç¶æ
- 该æä»¶å建çå ¨é¨èµæº
- 该æä»¶æä¾çå ¨é¨æå¡
å®ççå½å¨æå¯ä»¥ç®å为ï¼
PENDING â LOADING â ACTIVE â UNLOADING â DISPOSED
å ¶ä¸ï¼
PENDINGï¼ä¾èµå°æªåå¤å¥½ï¼ææ¶ä¸è¿è¡ï¼LOADINGï¼ä¾èµå·²æ»¡è¶³ï¼æ£å¨åå§åï¼ACTIVEï¼æä»¶æ£å¨æ£å¸¸å·¥ä½ï¼UNLOADINGï¼ä¾èµæ¶å¤±ãé ç½®æ´æ°ææä»¶ä¸»å¨å¸è½½ï¼DISPOSEDï¼ææèµæºå·²éæ¾ã
æä»¥ctx.plugin()è¿å Fiber å¾éè¦ï¼
constfiber =awaitctx.plugin(plugin)
awaitfiber.dispose()
è°ç¨dispose()并䏿¯âææä»¶å½æ°å
³æâè¿ä¹ç®åï¼èæ¯éæ¯è¯¥æä»¶æ´ä¸ªçå½å¨æå
建ç«çèµæºã
æä»¶æ³¨åå Fiber å建ç代ç ä½äºpackages/core/src/registry.tsï¼çå½å¨æç¶æä¸æ§è¡é»è¾ä½äºpackages/core/src/fiber.tsã
injectï¼Cordis çä¾èµæ³¨å ¥æ¯ä¸å¥æç»çæçä¾èµå ³ç³»
æ®éä¾èµæ³¨å ¥æ¡æ¶ç»å¸¸åªå¨åå§åæ¶æå¯¹è±¡ä¼ ç»ä½ ãCordis æ´è¿ä¸æ¥ï¼å®ä¼æç»è§å¯ä¾èµæ¯å¦å¯ç¨ã
ä¾å¦ï¼
constplugin = {
inject: ['database'],
apply(ctx) {
ctx.database.query('SELECT 1')
},
}
è¿éçinjectä¸åªæ¯ç±»å声æï¼å®åè¯ Cordisï¼åªædatabaseæå¡å¯ç¨æ¶ï¼è¿ä¸ªæä»¶æå¯ä»¥è¿è¡ã
å¦ææ°æ®åºå°æªå®è£ ï¼æä»¶ä¸ä¼æ¥éï¼ä¹ä¸ä¼æåæ§è¡ï¼èæ¯çå¨çå¾ ç¶æï¼
database å°ä¸åå¨
â
plugin ä¿æ PENDING
彿°æ®åºæå¡åºç°ï¼
database å·²æä¾
â
plugin å¼å§ LOADING
â
æ§è¡ apply(ctx)
â
plugin è¿å
¥ ACTIVE
å¦ææ°æ®åºåæ¥æå¼ãå¸è½½æè¢«æ¿æ¢ï¼
database 失æ
â
ä¾èµå®ç plugin å¸è½½
â
æ¸
çå®å建çèµæº
â
çå¾
æ°ç databaseï¼æä¿æ PENDING
å®ç°ä¸ï¼Fiber 伿ä¾èµæå¡å¯¹åºçè¿è¡å®ä¾ ID ç»åæÂ epochï¼çæ¬æ è¯ï¼ãåªè¦ä¾èµéåååï¼epoch å°±ä¼ååï¼Fiber 伿®æ¤æ§è¡å¸è½½æéæ°å è½½ã
è¿æå³ç Cordis 管çç䏿¯ä¸æ¬¡æ§çå¯¹è±¡æ³¨å ¥ï¼èæ¯âæå¡å¯ç¨æ§ä¸æä»¶è¿è¡ç¶æâçå ³ç³»ã
Serviceï¼æè½åæä¾å° Context ä¸
Cordis é常éè¿Serviceæ´é²é¿æåå¨çè½åï¼
classDatabaseextendsService{
constructor(ctx:Context) {
super(ctx,'database')
}
query(sql:string) {
// æ§è¡æ¥è¯¢
}
}
å®è£ åï¼
awaitctx.plugin(Database)
ctx.database.query('SELECT 1')
super(ctx, 'database')åçäºæ
æ¯æå½åå®ä¾æ³¨å为databaseæå¡ãä¹åå
¶ä»æä»¶åªé声æï¼
inject: ['database']
ç¶åå°±å¯ä»¥éè¿ctx.database使ç¨å®ã
æå¡ä¸ Fiber æ¯ç»å®çã妿æä¾æ°æ®åºæå¡çæä»¶è¢«å¸è½½ï¼ctx.databaseä¹ä¼èªå¨å¤±æï¼ä¾èµæ°æ®åºçæä»¶åä¼éä¹éè½½æåæ¢ã
å æ¤ï¼Cordis ä¸é¼å±æ è¾¹ççå ¨å±åéãæå¡æ»ææç¡®çæä¾è ãä½ç¨åä¸çå½å¨æã
effectï¼æå¯ä½ç¨æå°çå½å¨ææ ä¸
æä»¶ç»å¸¸ä¼åå»ºå¿ é¡»æ¸ ççèµæºï¼
- 宿¶å¨
- WebSocket
- æä»¶çå¬å¨
- æ°æ®åºè¿æ¥
- æ¶æ¯è®¢é
- åæä»¶
ä¾å¦åç宿¶å¨ï¼
consttimer =setInterval(task,1000)
妿æä»¶å¸è½½åå¿è®°æ§è¡clearInterval(timer)ï¼å®æ¶å¨ä»ä¼ç»§ç»è¿è¡ï¼è¿å°±æ¯èµæºæ³æ¼ã
Cordis 使ç¨ctx.effect()è§£å³è¿ä¸ªé®é¢ï¼
ctx.effect(() =>{
consttimer =setInterval(task,1000)
return() =>{
clearInterval(timer)
}
},'periodic task')
å ¶ä¸è¿åç彿°å°±æ¯æ¸ çé»è¾ã
å½æå±æä»¶è¢«å¸è½½æ¶ï¼Cordis ä¼èªå¨æ§è¡å®ï¼
å®è£
æä»¶
â
åå»ºå®æ¶å¨
â
å° clearInterval 注å为 effect
â
å¸è½½æä»¶
â
èªå¨æ§è¡ clearInterval
ctx.effect()æ¯æåæ¥æ¸
ç彿°ã弿¥æ¸
ç彿°ãçæå¨å弿¥çæå¨ãFiber å¸è½½æ¶ä¼ä»¥åå顺åºéæ¾å·²ç»è®°èµæºï¼ä¿è¯åå建çèµæºå
å
³éã
äºä»¶çå¬ä¹æ¯åæ ·çæºå¶ï¼
ctx.on('message', callback)
Cordis å¨å 鍿âåæ¶è¿ä¸ªçå¬å¨âç彿°æ³¨åå°å½å Fiberãå æ¤æä»¶å¸è½½åï¼å®æ³¨åçäºä»¶çå¬å¨ä¸ä¼æ®çã
妿æä»¶è¿å®è£ äºåæä»¶ï¼èµæºå ³ç³»ä¼å½¢æä¸æ£µæ ï¼
ç¶æä»¶
ââ äºä»¶çå¬
ââ 宿¶å¨
ââ åæä»¶
ââ WebSocket
å¸è½½ç¶æä»¶æ¶ï¼Cordis 伿åå顺åºéæ¾èµæºï¼ç¡®ä¿åå建çä¾èµèµæºå è¢«å ³éã
isolateï¼ååæå¡ä¸ºä»ä¹å¯ä»¥æå¤ä¸ªå®ä¾
å¨å¾å¤åºç¨ä¸ï¼åä¸ä¸ªæå¡åä¸ä¸å®åªå¯¹åºä¸ä¸ªå®ä¾ã
ä¾å¦ï¼å¤ç§æ·ç³»ç»ä¸æ¯ä¸ªç§æ·å¯è½æç¬ç«æ°æ®åºï¼
consttenantA = root.isolate('database')
consttenantB = root.isolate('database')
æ¥çå嫿便å¡ï¼
tenantA.provide('database', databaseA)
tenantB.provide('database', databaseB)
ç¶åï¼
tenantA.database// databaseA
tenantB.database// databaseB
è½ç¶ä¸¤è¾¹é½è®¿é®ctx.databaseï¼ä½åºå±å¹¶ä¸æ¯åä¸ä¸ªæå¡ã
Cordis ä¼ä¸ºè¢«é离çæå¡ååé ä¸åçå 鍿 è¯ï¼å æ¤æ¥æ¾æå¡æ¶è½å¤ç¡®å®å½å Context åºè¯¥çå°åªä¸ªå®ä¾ï¼
root
ââ tenantA
â ââ database â databaseA
â
ââ tenantB
ââ database â databaseB
åä¸ä¸ªæä»¶å¯ä»¥è¢«å®è£ å°ä¸¤ä¸ªä¸ä¸æä¸ï¼
awaittenantA.plugin(plugin)
awaittenantB.plugin(plugin)
æä»¶ä»£ç æ é夿èªå·±å±äºåªä¸ªç§æ·ï¼å®åªéè¦ä¾èµctx.databaseãè¿å°±æ¯ä½ç¨å带æ¥çç»åè½åã
Eventsï¼äºä»¶çå¬å¨ä¹æ¯æä½ç¨åçèµæº
Cordis çäºä»¶ç³»ç»æ¯æï¼
emit()ï¼åæ¥å¹¿æï¼parallel()ï¼å¹¶åæ§è¡å¹¶çå¾ ï¼serial()ï¼æé¡ºåºå¼æ¥æ§è¡ï¼å¾å°ç¬¬ä¸ä¸ªææç»æï¼bail()ï¼åæ¥çè·¯ï¼waterfall()ï¼ä¸é´ä»¶å¼è°ç¨é¾ã
çå¬å¨å¹¶ä¸æ¯ç®åå°åæ¾å¨å ¨å±æ°ç»ä¸ãæ¯ä¸ªçå¬å¨ä¼è®°å½å®å±äºåªä¸ª Contextï¼å¨äºä»¶ååæ¶ï¼Cordis 伿 ¹æ®å½åä¸ä¸æåé离è§åå³å®åªäºçå¬å¨å¯ä»¥ååºã
è¿å¸¦æ¥ä¸¤ä¸ªç»æï¼
- ä¸ä¸ªæä»¶å¸è½½åï¼å®æ³¨åççå¬å¨èªå¨æ¶å¤±ï¼
- ä¸åä½ç¨åçæä»¶ä¸ä¼æå¤å¤çå½¼æ¤çäºä»¶ã
å æ¤ï¼äºä»¶ç³»ç»ä¸æå¡ç³»ç»ä¸æ ·ï¼é½ä¸æ¯å ¨å±æ è¾¹ççã
é ç½®æ´æ°åçæ´æ°ä¸ºä»ä¹å¯è¡
Cordis çæä»¶ä¸æ¯ä¸æ¬¡æ§æ§è¡å®å°±å¤±å»æ§å¶ãæ¯ä¸ªæä»¶é½æèªå·±ç Fiberï¼å æ¤å½é ç½®ãä¾èµæä»£ç åçååæ¶ï¼æ¡æ¶å¯ä»¥æ§è¡ä¸å¥ç¡®å®çè¿ç¨ï¼
æ§ Fiber å¸è½½
â
éæ¾æ§äºä»¶ã计æ¶å¨ãè¿æ¥ä¸åæä»¶
â
ä¿çæ°çé
ç½®æä¾èµç¶æ
â
éæ°æ§è¡æä»¶
â
çææ°çèµæºæ
è¿æ£æ¯Â Loader å HMR è½å·¥ä½çåæã
Loader è´è´£æ ¹æ®é ç½®æä»¶æ¾å°å¹¶å è½½æä»¶ï¼HMR è´è´£å¨å¼åæ¶åç°æ¨¡åååå¹¶éè£ æä»¶ãå®ä»¬ä¹æä»¥ä¸å®¹æäº§çéå¤çå¬ãæ§è®¡æ¶å¨æ®ççé®é¢ï¼æ¯å 为 Cordis å·²ç»æå¯ä½ç¨æ¶æ¢å° Fiber çå½å¨æä¸ã
æ»ç»
Cordis çæ ¸å¿ææ³å¯ä»¥å½çº³ä¸ºä¸å¥è¯ï¼
ææä»¶çä¾èµãæå¡ãäºä»¶åå¯ä½ç¨é½æ¾è¿å¯è¿½è¸ªççå½å¨ææ ä¸ã
å®éè¿ï¼
Context + Proxyè§£æå½åä½ç¨åä¸çæå¡ï¼Fiberä»£è¡¨ä¸æ¬¡æä»¶è¿è¡ï¼injectç»´æ¤æå¡ä¾èµä¸æä»¶ç¶æï¼effectèªå¨è¿½è¸ªåéæ¾å¯ä½ç¨ï¼isolate让ååæå¡å¯ä»¥å¨ä¸åä¸ä¸æç¬ç«åå¨ï¼Events管çå¯ä½ç¨ååãå¯èªå¨åæ¶ççå¬å¨ã
æä»¥ Cordis çæ¬è´¨ä¸æ¯âæä¾ä¸å APIâï¼èæ¯æä¾ä¸ç§åºç¨ç»ç»æ¹å¼ï¼æ¨¡åè½è¢«å®è£ ãçå¾ ä¾èµãæä¾è½åãåå»ºèµæºãéè½½ï¼å¹¶å¨éåºæ¶å¹²åå°æ¶å¤±ã
å»ºè®®çæºç é 读顺åº
packages/core/src/context.tspackages/core/src/registry.tspackages/core/src/fiber.tspackages/core/src/reflect.tspackages/core/src/events.ts
Aitishiku.com