尧图精选

Dagger TypeScript SDK 中 FunctionCachePolicy 枚举详解:函数结果缓存的三级策略与源码级实现

🕒 发布时间:2026/9/17 4:08:38 📁 来源:尧图网络
Dagger TypeScript SDK 中 FunctionCachePolicy 枚举详解函数结果缓存的三级策略与源码级实现【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger本文以 Dagger 仓库中 TypeScript SDK 参考文档里的FunctionCachePolicy枚举为核心完整解读Default、Never、PerSession三个枚举值的语义与取值并结合 sdk/typescript/src/api/client.gen.ts 与 core/modfunc.go 的源码实现说明每个策略在引擎侧到底如何影响函数调用的缓存行为以及模块开发者在注册函数时如何指定缓存策略与 TTL。读完本文后你将能够准确选择缓存策略、正确传递timeToLive参数并理解策略从 SDK 到引擎的完整落地链路。枚举定义函数结果缓存的行为开关Dagger 官方 TypeScript SDK 参考文档见 FunctionCachePolicy 文档将该枚举描述为The behavior configured for function result caching.为函数结果缓存配置的行为。对应到 TypeScript 客户端生成代码中枚举定义非常精简sdk/typescript/src/api/client.gen.ts#L1894-L1898/** * The behavior configured for function result caching. */ export enum FunctionCachePolicy { Default Default, Never Never, PerSession PerSession, }三个枚举成员均为字符串字面量且成员名与值相同枚举成员字符串值语义FunctionCachePolicy.DefaultDefault使用默认的缓存行为跨调用缓存可配合 TTL 使用FunctionCachePolicy.NeverNever从不缓存函数结果每次调用都重新执行FunctionCachePolicy.PerSessionPerSession仅在当前会话session内缓存函数结果这种“成员名等于值”的设计是 Dagger SDK 生成枚举的通用约定SDK 通过 GraphQL 调用引擎时枚举以字符串形式序列化传输客户端代码中使用符号化的枚举成员即可无需手写魔法字符串。使用场景Function_.withCachePolicy 与 TTL 参数该枚举唯一的直接消费点是Function_对象的withCachePolicy方法sdk/typescript/src/api/client.gen.ts#L9026-L9045/** * Returns the function updated to use the provided cache policy. * param policy The cache policy to use. * param opts.timeToLive The TTL for the cache policy, if applicable. * Provided as a duration string, e.g. 5m, 1h30s. */ withCachePolicy ( policy: FunctionCachePolicy, opts?: FunctionWithCachePolicyOpts, ): Function_ { const metadata { policy: { is_enum: true, value_to_name: FunctionCachePolicyValueToName }, } const ctx this._ctx.select(withCachePolicy, { policy, ...opts, __metadata: metadata, }) return new Function_(ctx) }两个关键细节值得注意Function_是“函数定义”构造器属于模块开发module codegen链路的一部分。它描述的是“某个模块函数在被调用时应当如何缓存其结果”而不是普通container().withExec()这类核心 API 调用。opts.timeToLive是可选参数类型为时长字符串例如5m、1h30s其声明见 FunctionWithCachePolicyOptsexport type FunctionWithCachePolicyOpts { /** * The TTL for the cache policy, if applicable. Provided as a duration string, e.g. 5m, 1h30s. */ timeToLive?: string }注释中 “if applicable” 的措辞表明TTL 并非所有策略下都有意义从模块注册链路下文详述可以推断TTL 主要配合Default策略使用为缓存结果设置过期时间。引擎侧实现策略如何转化为隐式输入FunctionCachePolicy不只是客户端的序列化载体引擎会将其翻译为 DAG 计算图中的“隐式输入implicit input”从而决定缓存命中粒度。核心实现在 core/modfunc.go#L124-L139func (fn *ModuleFunction) cacheImplicitInputs() []dagql.ImplicitInput { if fn nil || fn.mod.Self() nil || fn.metadata nil { return nil } var implicitInputs []dagql.ImplicitInput cachePolicy : fn.metadata.derivedCachePolicy(fn.mod.Self()) switch cachePolicy { case FunctionCachePolicyNever: implicitInputs append(implicitInputs, dagql.PerCallInput) case FunctionCachePolicyPerSession: implicitInputs append(implicitInputs, dagql.PerSessionInput) } return implicitInputs }从这段源码结构可以清晰读出三种策略的落地差异Never→dagql.PerCallInput为该函数注入一个“每次调用都变化”的隐式输入。由于调用输入是缓存键的组成部分每次调用的键都不同结果必然无法命中缓存——等价于“每次调用都重新执行”。PerSession→dagql.PerSessionInput注入一个“会话内稳定、跨会话变化”的隐式输入。同一会话中相同参数调用会命中缓存会话结束或新会话开始时缓存自然失效。Default或策略为空→ 不追加隐式输入缓存键完全由显式调用输入决定只要输入不变结果可跨会话复用并可受 TTL 约束。这种“用隐式输入操纵缓存键”的实现方式与 Dagger 引擎基于内容寻址的 e-graph 缓存模型一脉相承开发者无需关心底层存储细节只需选择策略即可。模块开发视角策略值从装饰器到枚举的映射对于编写 Dagger 模块的开发者通常不直接手写FunctionCachePolicy而是通过模块函数上的缓存声明由 introspector 解析为方法元数据中的cache字段来指定策略。模块注册时的映射逻辑见 sdk/typescript/src/module/entrypoint/register.ts#L145-L161switch (fct.cache) { case never: { fnDef fnDef.withCachePolicy(FunctionCachePolicy.Never) break } case session: { fnDef fnDef.withCachePolicy(FunctionCachePolicy.PerSession) break } case : { break } default: { const opts: FunctionWithCachePolicyOpts { timeToLive: fct.cache } fnDef fnDef.withCachePolicy(FunctionCachePolicy.Default, opts) } }从这段分支结构看用户侧cache声明与枚举的对应关系是模块中声明的 cache 值映射到的 FunctionCachePolicy附加行为neverNever—sessionPerSession—空未声明不调用withCachePolicy沿用引擎默认行为—时长字符串如5mDefault将该字符串作为timeToLive传入最后一条分支恰好解释了FunctionWithCachePolicyOpts.timeToLive的典型用法当开发者希望“使用默认缓存行为但限定结果有效期”时声明一个时长字符串即可注册流程会自动将其包装为Default策略加 TTL 的组合。辅助工具枚举值与名称的相互转换生成代码同时提供了两个方向相反的转换函数服务于模块运行时的序列化边界sdk/typescript/src/api/client.gen.ts#L1900-L1936FunctionCachePolicyValueToName(value)将枚举值转换为名称字符串Default/Never/PerSession用于作为暴露函数的参数传递未识别的值原样返回。FunctionCachePolicyNameToValue(name)将名称字符串还原为枚举值用于在模块运行时内部正确消费该值未知名称直接as断言透传保持前向兼容。两者均对未知取值采取“原样透传”的宽松策略这意味着即使引擎侧未来新增枚举成员旧版 SDK 也不会直接抛错而是按字符串继续流转。同一枚举在 Go 运行时的镜像定义TypeScript 模块的运行时本身以 Go 形式执行因此同一套 API 在生成的 Go 客户端中也存在镜像枚举sdk/typescript/runtime/internal/dagger/dagger.gen.go#L16617-L16674type FunctionCachePolicy string const ( FunctionCachePolicyDefault FunctionCachePolicy Default FunctionCachePolicyPerSession FunctionCachePolicy PerSession FunctionCachePolicyNever FunctionCachePolicy Never )Go 版本额外提供Name()、Value()以及MarshalJSON/UnmarshalJSON方法保证 JSON 边界上的字符串编码与 TypeScript 侧完全一致同样以Default、Never、PerSession三个字符串为准。这确保了无论策略是在 TypeScript 层还是在 Go 运行时层被读取语义都不会漂移。小结选型建议与适用前提需要结果可跨会话复用的纯计算型函数保持默认或显式指定Default即可若结果会随时间失效例如拉取外部状态建议配合timeToLive使用Default策略。结果只应在当前会话内有效、跨会话必须重新求值时选择PerSession引擎注入PerSessionInput隐式输入。函数具有强副作用或需要每次调用都真实执行时选择Never引擎注入PerCallInput彻底绕开缓存命中。以上结论均以当前仓库代码为准枚举与转换函数定义于 sdk/typescript/src/api/client.gen.ts模块注册映射位于 sdk/typescript/src/module/entrypoint/register.ts引擎侧隐式输入逻辑位于 core/modfunc.go。文档路径位于 version-0.21 版本化参考目录读者在对照其他 SDK 版本或更新版本时建议以对应版本的生成代码为准。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →