8.9 KiB
description, kind
| description | kind |
|---|---|
| 带类型的 Client 到 Host 调用与 stream:分派、校验、取消、重连与转发的 Host 事件。 | package-reference |
@deepseek-ai/dsh-api-gateway
English | 中文
概述
为 Host 与 Client 两侧的 Cordis 环境提供 Typert RPC endpoint。Host 入口提供 ctx.typertGateway,@deepseek-ai/dsh-api-gateway/client 则提供 ctx.remote;两者使用同一份生成的 InvocationDescriptor 约定,并将业务选择交给 API Remotes。Connection 承载一元调用的请求关联、信任和响应 envelope,Gateway 则拥有多路复用的 Remote 流。
目录
- Host 服务:
TypertGatewayService(ctx key:typertGateway) - Client 服务:
ClientRemote(ctx key:remote) - 模型体验
- 已知限制与延期工作
- 开发备注
Host 服务:TypertGatewayService(ctx key:typertGateway)
每次调用时,ctx.typertGateway.invoke() 都会解析当前的描述符和 Cordis 服务,校验具名参数是否完全匹配,解析已注册的对象或 Context 身份标识,调用公开的业务方法,并校验其结果。业务服务继承 dsh-typert-protocol 的 TypertRemoteService,并用 @Remote 或 @RemoteScope 标记方法;已有其他基类时仍可改用 bindTypertRemote()。
严格模式从 ctx.typert.local 读取生成的调用描述符。查找参数使用 ctx.typert.lookups 中当前有效的 resolver:业务包注册稳定声明与默认策略,Host 组合可用 effect-scoped configure() 覆盖解析行为;@RemoteScope 则通过已注册的 Host Context adapter 解析其接收者。SRC 模式是开发阶段的回退路径,适用于从未具备严格定义的端点;它解析简单参数名,并且只允许非查找参数使用可安全表示为 JSON 的值。已观测到的严格定义一旦撤回,系统会直接报错,而不会降低校验强度。
Connection 可用时,Host 入口会在 Connection 共享的 /api FetchHandler 上注册 trusted-host interceptor。Connection 把这个复合 handler 交给 HTTP bridge;handler 将已认领 endpoint 分发给 Gateway,未认领 endpoint 则交给 API Proxy。直接调用 invoke() 会保留业务错误;TypertGatewayError 可区分分发、绑定、提供方、查找、Context、参数和编解码器各自负责的故障。resolver 可以用 TypertLookupFailure 携带既有 RPC error,使冷恢复失败或 ownership fence 等策略拒绝保持原错误码。
支持取消的 Remote 方法会把 signal: AbortSignal 声明为最后一个 Host 参数。signal 是 descriptor 元数据,而不是 wire 参数:Connection 将它提供给 Gateway,Gateway 则在已解码的业务参数之后注入它。SRC 识别这个保留的末位参数名,严格生成还要求它具有全局 AbortSignal 类型。
流式 Remote 使用 @Remote({ mode: 'stream' }) 并返回 Iterable 或 AsyncIterable。ctx.typertGateway.stream() 执行与一元调用相同的 endpoint、参数、lookup 和取消校验,再用生成的 result codec 校验每个产出项。Client 插件激活时打开 Gateway 自有的 /api/remote.mux WebSocket,使其在空闲时保持连接,并以有上限的退避重试物理连接失败。可独立取消的逻辑流共享这条连接;进程内 Connection 载体直接提供等价的流,不打开该 WebSocket。
Host 组合可通过 registerRemoteEvents() 注册唯一的应用事件 source。Gateway 为它保留内部 $events logical endpoint,只接受空 args,并在 source 撤回时中止该注册打开的 stream。事件名单、参数校验和每 Client 队列由 API Remotes 拥有。source factory 在返回 iterable 前同步挂好增量 listener;Gateway 随后先产出 { type: 'ready' },再迭代 source,让 Client 只在增量投递就绪后开始 baseline 读取。
Client 服务:ClientRemote(ctx key:remote)
ctx.remote.$mount() 会校验并注册生成的 Host-for-Client 贡献项,然后为发起调用的 Cordis fiber 安装具体的直接方法和作用域方法。每个 namespace 都是可追踪的 remote.<namespace> 子 Service,并在最后一个方法撤回后卸载。重复端点、命名空间冲突,以及缺少生成的严格编解码器的描述符,都会在方法可调用前报错。
每次一元调用都会校验位置参数,构造与描述符完全匹配的具名 args,再通过 ctx.connection.rpc.call('/api', endpoint, ...) 发送。生成的流方法返回 AsyncIterable,并在进程内 Connection 载体可用时通过它打开逻辑流,否则通过共享的 Gateway WebSocket 打开。生成的支持取消的方法接受最后一个可选 AbortSignal;Client 会在调用载体前将它与贡献项的挂载生命周期合并。一元结果和每个流项都经过校验后才会交给应用代码。撤回贡献项会同时移除其描述符和方法、中止正在进行的调用与流,并使外部仍持有的方法句柄在调用时返回拒绝。
ctx.remote.$stream() 返回跨越多个物理载体代次的单消费方 RemoteStream。Host 仍在线时,它允许一次立即重试;Host 离线时,它等待下一代连接,并为每个流项标注物理代次。领域消费方校验并接受各代次的 opening value;业务与协议错误仍然终止流。RemoteSnapshotStream 在此之上规定每代由一个 opening snapshot 和后续 delta 组成。RemoteJournalStream 基于领域提供的 entry 闭区间提供 follow-before-page、分页、重连追赶与缺口修复;它丢弃完整重复项,并拒绝缺口、倒置区间和部分重叠。dispose 任一种 stream 都会取消其请求,并在活动 iterator 完全停止后完成。
ctx.remote.$on() 订阅一条被转发的 Host 事件。它的合法键恰好等于 Host 装配声明的转发选择,listener 类型就是事件所属包自己的 Cordis Events 声明,因此不存在会与之漂移的第二份签名。每个订阅归属发起调用的 fiber,并随该 fiber 一起消失。Client Remote 服务激活时就把 $events pump 注册为 Connection generation source,因此即使当前无 $on 订阅,它也会在 Connection 循环启动时打开。浏览器使用 Remote mux,进程内组合使用 connection.rpc.open;ready 项与 host.describe 共同建立一个 Connection generation。物理 carrier 失败、Remote stream error、意外正常结束、非 ready 首项或畸形事件项都会终止该 generation,由 Connection 退避后重开。普通通知按注册顺序运行并隔离 listener 失败;Agent-scoped waterfall 允许 listener 返回结果、调用 next() 或拒绝,Gateway 再通过现有 HTTP 一元载体回送该结果。
生成的声明合并通过共享的 TypertClientRemote 约定提供 TypeScript API。Client 入口不包含 Host 服务或 Host Cordis 接口合并;方法查找和调用使用普通对象与函数,而不使用 JavaScript Proxy。
模型体验
无,因为该包分发应用调用,不注册任何提示词、工具或会话事件。
KV Cache 影响
无直接影响;被调用的业务服务负责产生任何模型可见结果。
已知限制与延期工作
- Connection 适配器将普通分发故障和业务异常映射为 RPC 的
internal代码,且不附带详细信息;TypertLookupFailure携带的 lookup 策略错误会原样返回。结构化的TypertGatewayError类别仅供同进程调用方使用。 - SRC 模式仅支持名称唯一的标识符参数,不支持解构、默认值或剩余参数。它只校验值能否安全表示为 JSON,不校验生成的业务类型,也绝不会推断可选字段。
- Client 侧只能挂载严格模式生成的贡献项。SRC 标记不具备 Client 编解码器或类型投影。
$stream()监督载体替换,但不推断回放语义;各领域自行拥有恢复 cursor 或替换 baseline 的校验,以及正常结束的分类。Connection generation 会重开内部$events;单向通知不会重放,仍处于 pending 的 scoped waterfall 则沿用同一个 event id 重放。- lookup resolver 按 key 配置;当前无法让单个 Remote 参数或 endpoint 在同一
agent/sessionkey 下选择 live-only 策略。 - 被转发的事件到达
$on时不做业务载荷投影或脱敏。普通通知在重连后不重放;Agent-scoped waterfall 只投影选择 Client Context 所需的顶层 Agent 身份,并自行携带 pending 生命周期。
开发备注
维护者工作上下文——点击展开
无。