Dagger TypeScript SDK 指南:EngineCacheEntrySet 缓存条目集 API 详解
【免费下载链接】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 仓库docs/versioned_docs/version-0.19下的 TypeScript API 参考文档为主体,系统讲解EngineCacheEntrySet(引擎缓存条目集)类的构造方式、四个核心方法及其配套的类型别名(EngineCacheEntrySetID、EngineCacheEntrySetOpts),并结合仓库源码(core/schema/engine.go 与 sdk/typescript/src/api/client.gen.ts)说明其底层调用链。读完本文,你将掌握如何在 TypeScript 中通过dagger.engineCache().entrySet()查询 Dagger 引擎缓存占用,逐条枚举缓存条目,并理解该方法在引擎侧的解析逻辑与安全约束。
类概览:什么是 EngineCacheEntrySet
根据官方 API 文档的定义,EngineCacheEntrySet是:
A set of cache entries returned by a query to a cache
即"一次缓存查询所返回的一组缓存条目"。它由EngineCache.entrySet()方法产生(详见 EngineCache 类文档),用来聚合描述引擎本地缓存当前的状态——包括占用空间总量、条目数量,以及每个独立条目的明细。
从类的继承关系看,EngineCacheEntrySet直接继承自BaseClient,这意味着它复用 Dagger TypeScript SDK 的统一客户端上下文(Context),所有查询字段的取值都通过内部 GraphQL 客户端按需执行(lazy evaluation)。
在 GraphQL 层,EngineCacheEntrySet实现了Node接口,对应的类型定义位于 core/schema/testdata/base_schema.graphqls:
type EngineCacheEntrySet implements Node { """The total disk space used by the cache entries in this set.""" diskSpaceBytes: Int! """The list of individual cache entries in the set""" entries: [EngineCacheEntry!]! """The number of cache entries in this set.""" entryCount: Int! """A unique identifier for this EngineCacheEntrySet.""" id: ID! }这 4 个字段与 TypeScript 类的 4 个公开方法一一对应,是理解该类的最小信息面。
构造函数:仅供内部使用
文档明确指出该构造函数仅限 SDK 内部使用,不要在业务代码中手动new EngineCacheEntrySet(...):
new EngineCacheEntrySet( ctx?: Context, _id?: EngineCacheEntrySetID, _diskSpaceBytes?: number, _entryCount?: number, ): EngineCacheEntrySet参数ctx为客户端上下文,_id、_diskSpaceBytes、_entryCount均为带下划线前缀的私有字段,由 Dagger 引擎返回结果时填充。对应的 TypeScript 生成代码见 sdk/typescript/src/api/client.gen.ts:
export class EngineCacheEntrySet extends BaseClient { private readonly _id?: ID = undefined private readonly _diskSpaceBytes?: number = undefined private readonly _entryCount?: number = undefined constructor( ctx?: Context, _id?: ID, _diskSpaceBytes?: number, _entryCount?: number, ) { super(ctx) this._id = _id this._diskSpaceBytes = _diskSpaceBytes this._entryCount = _entryCount } // ... }一个值得注意的实现细节是:diskSpaceBytes与entryCount方法在取值时会优先返回构造时已缓存的本地字段,仅当字段未填充时才向引擎发起 GraphQL 查询(见 client.gen.ts 中if (this._diskSpaceBytes)、if (this._entryCount)的短路逻辑)。因此在一次 GraphQL 响应内已携带的聚合数据不会产生额外往返。
公开方法详解
id():获取唯一标识符
id(): Promise<EngineCacheEntrySetID>返回该EngineCacheEntrySet的唯一标识符。文档描述为:
A unique identifier for this EngineCacheEntrySet.
其类型EngineCacheEntrySetID定义于 type-aliases/EngineCacheEntrySetID.md:
type EngineCacheEntrySetID = string & { __EngineCacheEntrySetID: never }这是一个"品牌化字符串"(branded string)类型:底层是字符串,但通过交叉一个永不为真的__EngineCacheEntrySetID: never字段形成名义类型,防止与其他 ID 类型混用。该 ID 可通过 GraphQL 的loadEngineCacheEntrySetFromID(id: EngineCacheEntrySetID!): EngineCacheEntrySet!重新加载对象(见 base_schema.graphqls)。
在生成代码中,id()会选择 GraphQL 字段id并执行查询(client.gen.ts):
id = async (): Promise<ID> => { if (this._id) { return this._id } const ctx = this._ctx.select("id") const response: Awaited<ID> = await ctx.execute() return response }diskSpaceBytes():查询集合总占用
diskSpaceBytes(): Promise<number>返回该集合内所有缓存条目占用的总磁盘空间(字节),对应 GraphQL 字段diskSpaceBytes: Int!,在 Go 引擎侧由EngineCacheEntrySet.DiskSpaceBytes字段承载。典型用途是评估引擎本地缓存的体积,配合EngineCache.maxUsedSpace()/EngineCache.minFreeSpace()(见 EngineCache 类文档)判断缓存策略是否健康。
entryCount():查询条目数量
entryCount(): Promise<number>返回该集合中缓存条目的数量,对应 GraphQL 字段entryCount: Int!。它与diskSpaceBytes()的组合可以计算"平均条目占用",辅助判断是否存在体积异常巨大的缓存条目。
entries():枚举所有缓存条目
entries(): Promise<EngineCacheEntry[]>返回该集合中所有独立缓存条目的列表,每个元素是EngineCacheEntry对象。EngineCacheEntry类文档见 classes/EngineCacheEntry.md,其自身提供以下查询方法:
| 方法 | 返回类型 | 语义 |
|---|---|---|
activelyUsed() | Promise<boolean> | 该条目是否正在被使用 |
createdTimeUnixNano() | Promise<number> | 条目的创建时间(Unix 纳秒) |
description() | Promise<string> | 条目的描述信息 |
diskSpaceBytes() | Promise<number> | 该条目占用的磁盘空间(字节) |
id() | Promise<EngineCacheEntryID> | 该条目的唯一标识符 |
mostRecentUseTimeUnixNano() | Promise<number> | 条目的最近使用时间(Unix 纳秒) |
entries()的生成代码展示了 SDK 的惰性查询模式(client.gen.ts):先选择entries字段并附带id子选择,待执行返回 ID 列表后,再通过new EngineCacheEntry(ctx.copy().selectNode(r.id, "EngineCacheEntry"))为每个 ID 重建客户端节点,供后续按需调用各属性方法:
entries = async (): Promise<EngineCacheEntry[]> => { const ctx = this._ctx.select("entries").select("id") const response: Awaited<entries[]> = await ctx.execute() return response.map( (r) => new EngineCacheEntry(ctx.copy().selectNode(r.id, "EngineCacheEntry")), ) }而 Go 引擎侧,entries解析器只是直接返回父对象中已加载的条目列表(core/schema/engine.go):
func (s *engineSchema) cacheEntrySetEntries(ctx context.Context, parent *core.EngineCacheEntrySet, args struct{}) (dagql.Array[*core.EngineCacheEntry], error) { return parent.EntriesList, nil }配套类型别名:EngineCacheEntrySetOpts
EngineCacheEntrySetOpts是EngineCache.entrySet()的选项对象(type-aliases/EngineCacheEntrySetOpts.md),目前仅含一个可选属性:
type EngineCacheEntrySetOpts = { key?: string }key用于按缓存键过滤条目集。在 Go 引擎的cacheEntrySet解析器中(core/schema/engine.go),key的默认值为空字符串(default:""),其处理逻辑分两支:
- key 为空(未指定):引擎会生成一个全新的随机
identity.NewID()作为查询键,此时返回的是"当前查询对应的空条目集占位对象"(通过srv.Select将EngineCache.entrySet(key: ...)下发给底层服务),即该集合不代表任何真实缓存内容; - key 非空:调用
query.EngineLocalCacheEntries(ctx)从引擎本地缓存加载真实条目,并包装为EngineCacheEntrySet返回。
GraphQL 侧的字段声明为entrySet(key: String = ""): EngineCacheEntrySet!(见 base_schema.graphqls),与 Go 的default:""标签一致。
从源码看调用链与权限约束
EngineCacheEntrySet并不是独立创建的对象,其完整调用链为:
TypeScript: dagger.engineCache().entrySet({ key }) → GraphQL: engineCache { entrySet(key: String = "") { id diskSpaceBytes entryCount entries { ... } } } → Go: engineSchema.cacheEntrySet (core/schema/engine.go#L106) → 引擎本地缓存: EngineLocalCacheEntries (core.EngineCacheEntrySet)两个关键安全约束值得注意:
cacheEntrySet与cachePrune一样,都会先调用query.RequireMainClient(ctx)(engine.go)。这意味着读取缓存条目集要求当前会话是主客户端(main client),普通模块或子会话不能直接枚举引擎缓存,防止缓存信息泄露或误操作。entries的解析不触发新的缓存扫描,直接返回parent.EntriesList(engine.go),说明引擎在创建条目集时已经完成一次快照,entries()读取的是快照数据。
另外,测试侧对同一类型的封装可见于 core/schema/test_server_test.go:EngineLocalCacheEntries返回*core.EngineCacheEntrySet,PruneEngineLocalCacheEntries则在裁剪后返回新的条目集——这说明该类型同时服务于"查询缓存状态"与"裁剪后复查"两个场景,与EngineCache.prune()(见 EngineCache 类文档)构成完整的缓存治理闭环。
实践:一个完整的 TypeScript 用法示例
基于上述 API,可以编写一个完整的缓存状态检查脚本(需要@dagger.io/dagger客户端已连接引擎,且会话为主客户端):
import { connect } from "@dagger.io/dagger" connect(async (client) => { // 1. 通过 engineCache().entrySet() 获取当前缓存条目集 // 不传 key 时,返回的集合由引擎按当前查询上下文生成 const cache = client.engineCache() const entrySet = cache.entrySet() // 2. 查询集合级聚合指标 const totalBytes = await entrySet.diskSpaceBytes() const count = await entrySet.entryCount() console.log(`cache entries: ${count}, total disk: ${totalBytes} bytes`) // 3. 遍历每条缓存条目,输出明细 const entries = await entrySet.entries() for (const entry of entries) { const id = await entry.id() const bytes = await entry.diskSpaceBytes() const active = await entry.activelyUsed() const created = await entry.createdTimeUnixNano() const lastUsed = await entry.mostRecentUseTimeUnixNano() console.log({ id, bytes, active, created: new Date(created / 1e6).toISOString(), lastUsed: new Date(lastUsed / 1e6).toISOString(), }) } })要点说明:
- 条目级字段(创建时间、最近使用时间)以Unix 纳秒为单位(
createdTimeUnixNano、mostRecentUseTimeUnixNano),转毫秒需除以1e6才能用于Date; id()返回的是品牌化 ID 类型EngineCacheEntrySetID/EngineCacheEntryID,可用作后续 GraphQLloadEngineCacheEntrySetFromID的入参实现跨会话恢复;- 由于方法返回 Promise,建议在
connect回调中组合使用await或Promise.all控制并发。
相关 API 导航
围绕EngineCacheEntrySet,以下几个文档与源码可作为继续深入的路标:
- EngineCache 类文档:
entrySet()的宿主类型,同时提供prune()、maxUsedSpace()、minFreeSpace()、reservedSpace()、targetSpace()等缓存治理方法; - EngineCacheEntry 类文档:条目明细对象的字段与方法;
- EngineCacheEntrySetID 类型文档 与 EngineCacheEntrySetOpts 类型文档:配套类型定义;
- GraphQL 类型定义与 ID 加载入口:base_schema.graphqls;
- Go 引擎解析器实现:core/schema/engine.go;
- TypeScript SDK 生成代码:sdk/typescript/src/api/client.gen.ts。
EngineCacheEntrySet是 Dagger 引擎缓存观测与治理链路中的核心数据载体:通过entrySet获取聚合快照,用diskSpaceBytes()、entryCount()评估缓存体积,用entries()逐条审视缓存内容,再配合EngineCache.prune()完成释放——这套 API 组合足以支撑缓存体检、容量告警与定向清理等自动化运维场景。
【免费下载链接】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),仅供参考