news 2026/9/15 3:30:26

Dagger EngineCacheEntry 完全指南:用 TypeScript SDK 读取与分析引擎缓存条目的 5 个核心方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dagger EngineCacheEntry 完全指南:用 TypeScript SDK 读取与分析引擎缓存条目的 5 个核心方法

Dagger EngineCacheEntry 完全指南:用 TypeScript SDK 读取与分析引擎缓存条目的 5 个核心方法

【免费下载链接】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

导读

EngineCacheEntry是 Dagger TypeScript SDK(@dagger.io/dagger)中用于描述引擎缓存中单个缓存条目的客户端类,它把 Dagger 引擎(Engine)本地缓存里每一条记录(如源码检出、依赖缓存、exec.cachemount挂载点等)抽象为可查询的对象。本文以官方 API 文档(classes/EngineCacheEntry.md)为骨架,结合仓库内 SDK 生成源码、核心引擎实现与集成测试,完整讲解该类的构造规则、6 个实例方法、底层数据来源,以及如何通过engine.cache().entrySet().entries()链路实际读取缓存条目,帮助你构建缓存可视化、容量审计与占用分析工具。

一、EngineCacheEntry 在 Dagger 缓存体系中的位置

在 Dagger 的 TypeScript API 中,缓存相关对象构成一条清晰的查询链:

Client.engine() → EngineCache → entrySet() → EngineCacheEntrySet → entries() → EngineCacheEntry[]
  • EngineCache 代表 "A cache storage for the Dagger engine"(引擎的缓存存储),通过entrySet()方法返回一个缓存条目集合;
  • EngineCacheEntrySet描述 "A set of cache entries returned by a query to a cache"(一次缓存查询返回的条目集合),提供entries()entryCount()diskSpaceBytes()
  • EngineCacheEntry则是集合中的单个成员,官方定义为 "An individual cache entry in a cache entry set"。

在引擎侧,对应数据结构定义于 core/engine.go:

type EngineCacheEntry struct { Description string `field:"true" doc:"The description of the cache entry."` DiskSpaceBytes int `field:"true" doc:"The disk space used by the cache entry."` CreatedTimeUnixNano int `field:"true" doc:"The time the cache entry was created, in Unix nanoseconds."` MostRecentUseTimeUnixNano int `field:"true" doc:"The most recent time the cache entry was used, in Unix nanoseconds."` ActivelyUsed bool `field:"true" doc:"Whether the cache entry is actively being used."` RecordType string `field:"true" doc:"The type of the cache record (e.g. regular, internal, frontend, source.local, source.git.checkout, exec.cachemount)."` RecordTypes []string `field:"true" doc:"The storage record types represented by this cache entry."` DagqlCall string `field:"true" doc:"The DagQL call that produced this cache entry."` }

也就是说,一条缓存条目至少携带:描述、磁盘占用(字节)、创建时间(Unix 纳秒)、最近使用时间(Unix 纳秒)、是否正在被使用这五类信息。其中RecordType的取值示例(regularinternalfrontendsource.localsource.git.checkoutexec.cachemount)揭示了 Dagger 缓存条目的来源多样性——从本地目录源、Git 检出到WithMountedCache的挂载缓存都各有独立的记录类型。

二、类概览:继承关系与构造约束

2.1 继承关系

EngineCacheEntry直接继承自BaseClient。所有 Dagger TypeScript SDK 客户端类都共享这一基类,因此该类天然具备惰性执行 GraphQL 查询、上下文传递等通用能力。在生成源码 sdk/typescript/src/api/client.gen.ts 中可以看到它持有以下私有字段:

export class EngineCacheEntry extends BaseClient { private readonly _id?: ID = undefined private readonly _activelyUsed?: boolean = undefined private readonly _createdTimeUnixNano?: number = undefined private readonly _dagqlCall?: string = undefined private readonly _description?: string = undefined private readonly _diskSpaceBytes?: number = undefined private readonly _mostRecentUseTimeUnixNano?: number = undefined private readonly _recordType?: string = undefined ... }

2.2 构造器:仅供内部使用

new EngineCacheEntry( ctx?: Context, _id?: EngineCacheEntryID, _activelyUsed?: boolean, _createdTimeUnixNano?: number, _description?: string, _diskSpaceBytes?: number, _mostRecentUseTimeUnixNano?: number, ): EngineCacheEntry

文档与源码均明确标注:"Constructor is used for internal usage only, do not create object from it."(构造器仅供内部使用,请勿自行创建对象)。所有参数均为可选,由 SDK 在解析 GraphQL 响应时自动填充。开发者应当通过查询链路获取实例,而不是new一个出来——这也符合 Dagger 客户端"查询即构建"的设计哲学:对象代表的是对引擎的一次查询描述,而非本地数据快照。

三、核心方法逐一解析

EngineCacheEntry共暴露 6 个实例方法(均为异步方法),下表先做总览:

方法返回类型语义
id()Promise<EngineCacheEntryID>该缓存条目的唯一标识符
description()Promise<string>缓存条目的描述文本
diskSpaceBytes()Promise<number>缓存条目占用的磁盘空间(字节)
createdTimeUnixNano()Promise<number>缓存条目创建时间(Unix 纳秒)
mostRecentUseTimeUnixNano()Promise<number>缓存条目最近一次被使用的时间(Unix 纳秒)
activelyUsed()Promise<boolean>缓存条目当前是否正被使用

3.1 id():唯一标识

id(): Promise<EngineCacheEntryID>

返回 "A unique identifier for this EngineCacheEntry"(该缓存条目的唯一标识)。其返回类型EngineCacheEntryID在 type-aliases/EngineCacheEntryID.md 中定义为string & { __EngineCacheEntryID: never }的交叉类型,是一个结构化字符串标量,代表 "an identifier for an object of type EngineCacheEntry"。

注意它在 SDK 中的实现带有短路缓存:若构造时已传入_id,直接返回本地值,否则才发起 GraphQL 选择器id的查询。这也解释了为何entries()返回的每个EngineCacheEntry都能携带已解析的 ID。

3.2 description():人类可读描述

description(): Promise<string>

返回 "The description of the cache entry"。对应引擎侧Description字段,用于向运维人员说明该条目是什么(例如某次源码检出或某个依赖层的描述文本),是排查"这条缓存到底是谁产生的"时的首要字段。

3.3 diskSpaceBytes():磁盘占用

diskSpaceBytes(): Promise<number>

返回 "The disk space used by the cache entry",单位是字节。配合EngineCacheEntrySet.diskSpaceBytes()(整个集合的总占用)可用于:

  • 统计缓存总量与单条最大占用;
  • 找出"缓存大头",决定清理优先级;
  • EngineCachemaxUsedSpace()minFreeSpace()等容量策略对照,评估当前缓存水位。

3.4 createdTimeUnixNano():创建时间

createdTimeUnixNano(): Promise<number>

返回 "The time the cache entry was created, in Unix nanoseconds"(Unix 纳秒精度的时间戳)。由于 Go 侧类型为int,JS 中对应number;如需转换为毫秒,可除以1_000_000。该时间戳可用来筛选"很久未创建、很可能可回收"的冷条目。

3.5 mostRecentUseTimeUnixNano():最近使用时间

mostRecentUseTimeUnixNano(): Promise<number>

返回 "The most recent time the cache entry was used, in Unix nanoseconds"。相比创建时间,这个字段更能反映缓存条目的活跃度:即使创建了很久,只要最近仍在使用,就不宜优先清理。它常与activelyUsed()组合,作为评估缓存淘汰价值的两个关键信号。

3.6 activelyUsed():活跃状态

activelyUsed(): Promise<boolean>

返回 "Whether the cache entry is actively being used"(当前是否正被活跃使用)。正在被运行中的执行任务引用的缓存条目会被标记为true,这类条目在清理时应被保护,避免破坏正在进行的构建。

四、实战:读取并遍历全部缓存条目

4.1 完整调用链示例

由于构造器仅供内部使用,实际获取EngineCacheEntry实例的唯一途径是走查询链路。参考 core/schema/engine.go 中entrySet解析器与 SDK 生成的EngineCacheEntrySet.entries()(见 client.gen.ts),典型 TypeScript 代码为:

import { connect } from "@dagger.io/dagger" connect(async (client) => { // 1. 拿到引擎缓存 const cache = client.engine().cache() // 2. 获取缓存条目集合(可按 key 过滤) const entrySet = cache.entrySet() // 3. 遍历每一条缓存条目并读取其属性 const entries = await entrySet.entries() console.log(`total entries: ${await entrySet.entryCount()}`) console.log(`total disk space (bytes): ${await entrySet.diskSpaceBytes()}`) for (const entry of entries) { const description = await entry.description() const diskBytes = await entry.diskSpaceBytes() const createdNs = await entry.createdTimeUnixNano() const lastUsedNs = await entry.mostRecentUseTimeUnixNano() const inUse = await entry.activelyUsed() const id = await entry.id() console.log({ id, description, diskBytes, createdMs: createdNs / 1_000_000, lastUsedMs: lastUsedNs / 1_000_000, activelyUsed: inUse, }) } })

4.2 entrySet 的 key 参数

cache.entrySet()支持可选的key参数(EngineCacheEntrySetOpts)。从 core/schema/engine.go 的实现看:

  • key默认值为空字符串;
  • key为空时,解析器会生成一个随机identity.NewID()作为 key 重新查询——即"不指定 key 就返回当前默认缓存集合";
  • 当指定 key 时,调用query.EngineLocalCacheEntries(ctx)加载对应的缓存条目集合。

4.3 惰性查询机制

观察 SDK 生成代码可以发现,每个访问器都遵循"本地已有值直接返回,否则按需发起 GraphQL 选择器查询"的模式,例如:

activelyUsed = async (): Promise<boolean> => { if (this._activelyUsed) { return this._activelyUsed } const ctx = this._ctx.select("activelyUsed") const response: Awaited<boolean> = await ctx.execute() return response }

这意味着循环中逐个调用description()diskSpaceBytes()等会产生多次引擎往返。如果在意性能,建议按需读取字段,或将多个标量字段的选择合并到一次 GraphQL 查询中执行。

五、底层实现:从 GraphQL 到引擎查询

5.1 Schema 层

EngineCacheEntry并非独立的根查询对象,而是挂在EngineCache下的子对象。在 core/schema/engine.go 中,Schema 注册了:

  • entrySet字段(带可选key参数)用于返回EngineCacheEntrySet
  • entries字段(cacheEntrySetEntries,见同文件第 186 行起)用于展开集合中的单个条目列表。

同时该文件还展示了配套的cachePrune方法(第 144 行起),参数包括useDefaultPolicymaxUsedSpacereservedSpaceminFreeSpacetargetSpace以及结构化元数据估算值maxEstimatedBytestargetEstimatedBytes——说明读取条目只是缓存治理的一半,另一半是修剪(prune)。

5.2 引擎查询接口

从源码结构看,真正加载缓存条目的是引擎查询接口 core/query.go 中声明的:

EngineLocalCacheEntries(context.Context) (*EngineCacheEntrySet, error) PruneEngineLocalCacheEntries(context.Context, EngineCachePruneOptions) (*EngineCacheEntrySet, error)

值得注意的细节是,cacheEntrySet解析器首先调用query.RequireMainClient(ctx),这意味着该 API 仅在主客户端会话上下文可用,对非主客户端(如某些子会话)会直接报错——这是使用时需要留意的限制。

5.3 测试验证

集成测试 core/integration/localcache_test.go 提供了消费该 API 的完整参考:getCacheEntryVals辅助函数依次调用DescriptionDiskSpaceBytesCreatedTimeUnixNanoMostRecentUseTimeUnixNanoActivelyUsedRecordTypeRecordTypesDagqlCall并断言无错误。它同时印证了底层条目的字段比 0.19 版 TypeScript 文档暴露的 6 个方法更丰富——当前仓库的引擎模型还包含RecordTypeRecordTypesDagqlCall三个附加字段,可以推断后续版本 SDK 可能会逐步暴露这些能力。

六、相关类型与配套能力

6.1 EngineCacheEntryID

EngineCacheEntryIDid()的返回类型,定义见 type-aliases/EngineCacheEntryID.md。它是一个不透明(opaque)字符串类型(string & { __EngineCacheEntryID: never }),你不能也不应手工构造其值,只能通过查询获得,并在同一会话内用它引用对应条目。

6.2 EngineCacheEntrySet

集合类型 classes/EngineCacheEntrySet.md 提供三个方法:

  • id():集合唯一标识;
  • diskSpaceBytes():集合内所有条目磁盘占用总和;
  • entryCount():集合内条目数量;
  • entries():返回EngineCacheEntry[]数组。

从生成源码看,entries()的实现会先只查询每个条目的id,再通过selectNode(r.id, "EngineCacheEntry")按 ID 重建每个条目对象(见 client.gen.ts)——这也是为什么上面实战示例中循环内每个访问器都是独立的懒查询。

6.3 上游 EngineCache

想要进一步管理缓存,classes/EngineCache.md 还提供maxUsedSpace()minFreeSpace()reservedSpace()targetSpace()等容量配置读取方法,以及prune()修剪方法(参数同上文 schema 中的EngineCachePruneOpts)。典型治理流程是:entrySet().entries()审计每条条目的磁盘占用与活跃度,再决定是否调用prune()释放空间

七、使用注意事项小结

  1. 不要手动构造:构造器仅供内部使用,务必通过client.engine().cache().entrySet().entries()获取实例。
  2. 单位约定diskSpaceBytes单位为字节;两个时间字段单位为 Unix 纳秒,展示给用户前建议换算为毫秒/秒。
  3. 惰性求值:每个访问器都是独立 GraphQL 查询,批量场景注意合并查询或缓存结果,避免 N+1 次引擎往返。
  4. 主客户端限制entrySet解析器要求主客户端上下文(RequireMainClient),在受限会话中可能不可用。
  5. 活跃标记是瞬态activelyUsed()反映的是查询时刻的状态,正在被执行的任务引用的条目为true,清理策略应优先保护这类条目。
  6. 字段在演进:当前仓库引擎模型还定义了RecordType(取值如source.localsource.git.checkoutexec.cachemount等)、RecordTypesDagqlCall,可作为理解未来版本 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 3:29:03

基于SSM的出版社教材服务网站:从毕设选题到答辩的全流程解析

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

作者头像 李华
网站建设 2026/9/15 3:27:29

1100张老鼠图像如何训练YOLOv8?小目标检测调优实战

简介&#xff1a;这是一份面向目标检测任务的老鼠图像数据集&#xff0c;共包含约1100张已标注图片&#xff0c;采用YOLO标注格式&#xff0c;类别仅“老鼠”一类&#xff0c;适合需要训练老鼠检测模型、开展YOLO系列改进实验或进行迁移学习的研究者与开发者。资源包共2000个文…

作者头像 李华
网站建设 2026/9/15 3:26:28

服务器故障排查清单:12种常见问题定位与处理全指南

做服务器运维这些年&#xff0c;我最怕听到的一句话不是“服务器挂了”&#xff0c;而是电话那头补一句“你自己看吧&#xff0c;我啥也没动”。半夜两点的机房告警&#xff0c;周末的微信轰炸&#xff0c;新手接手一台来历不明的服务器&#xff0c;面对的往往是一个黑盒加一堆…

作者头像 李华
网站建设 2026/9/15 3:26:09

AI时代CLI工具复兴:高效开发与自动化实践

1. AI Agent时代CLI复兴现象解析最近半年在开发者社区观察到一个有趣现象&#xff1a;当各大科技公司都在为AI Agent开发华丽的图形界面时&#xff0c;一批以Codex CLI、Gemini CLI为代表的新型命令行工具却逆势崛起。我的团队在开发AI辅助编程工具时&#xff0c;最初也设计了完…

作者头像 李华
网站建设 2026/9/15 3:24:52

嵌入式低功耗策略:收益量化、风险权衡与平衡之道

做嵌入式这些年&#xff0c;我最深的体会是&#xff1a;低功耗策略这项工作是典型的“表面越简单&#xff0c;背后越复杂”。一块电池、一颗MCU、一个无线模组&#xff0c;看起来只要让设备多睡一会儿就能省电&#xff0c;可真把功耗曲线打出来&#xff0c;你会发现每一微安都在…

作者头像 李华