wing 云队列 pop 行为测试快照解析:sim 平台 timeout 限制与跨平台实现差异
编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载导读本文以 winglang 仓库 hangar 测试工具生成的快照 pop.test.w_test_sim.md 为线索完整解读cloud.Queue.pop()在 sim 平台下的测试行为、Queue.timeout配置在 sim 平台不支持的原因以及 hangar 快照体系的生成机制。读完本文你将理解 wing 中队列pop()的语义非 FIFO、消息可见性超时、空队列返回nil掌握 sim 与 tf-aws 两种平台在队列实现上的根本差异并能看懂 hangar 快照中unsupported与skipped状态的含义。快照文件是什么一次 不支持 的测试记录该快照是 wing 官方 SDK 测试集在 sim 平台上运行pop.test.w后留下的标准输出记录其内容看似只有一段报错日志却完整展示了 hangar 快照体系的三种典型状态运行结果、编译产物、平台能力限制。快照正文结构如下Error: Queue.timeout is not supported on the sim platform yet. For more information see: https://github.com/winglang/wing/issues/1980. Contributions welcome ❤️ -- pop.test.w:5:9 | bring util; | | let timeout 3s; 5 | let q new cloud.Queue(timeout: timeout); | ^ at ABSOLUTE/pop.test.w:5:9 Tests 1 unsupported (1) Snapshots 1 skipped Test Files 1 unsupported (1) Duration DURATION要点逐条解读错误行号精确到源码位置pop.test.w:5:9指向new cloud.Queue(timeout: timeout)这一行说明编译器/运行时在 preflight 阶段构造队列时就拦截了timeout参数错误文案自述平台限制Queue.timeout is not supported on the sim platform yet. 是 SDK 源码中明确抛出的NotImplementedError见下文源码章节DURATION是快照归一化占位符hangar 在生成快照时会归一化随机数与绝对路径如ABSOLUTE保证快照内容可重复对比统计行Tests 1 unsupported (1)表示本文件 1 个测试因平台不支持而跳过Snapshots 1 skipped表示对应的测试快照未生成。快照文件名遵循 hangar 的命名约定{测试文件名}_{用例类型}_{目标平台}.md即pop.test.wtestwing test命令simsim 平台。同目录下还有一个配对快照 pop.test.w_compile_tf-aws.md记录的是同一文件在 tf-aws 平台的wing compile产物二者形成鲜明的跨平台对照。测试用例源码pop 的完整语义验证快照指向的源测试文件是 pop.test.w快照首行的相对链接../../../../../../tests/sdk_tests/queue/pop.test.w即指向该文件。完整源码如下bring cloud; bring util; let timeout 3s; let q new cloud.Queue(timeout: timeout); test pop { q.push(Foo, Bar); let first q.pop(); let second q.pop(); // ensure messages are deleted after timeout util.sleep(timeout); let third q.pop(); // queue is not FIFO assert(first Foo || first Bar); assert(second Foo || second Bar); assert(third nil); }该用例一口气验证了pop()的三条核心语义验证点代码表达含义按序弹出两条消息q.push(Foo, Bar)后两次q.pop()队列可以反复弹出消息且每条消息只被弹出一次非 FIFO 特性assert(first Foo \|\| first Bar)cloud.Queue默认不是 FIFO 队列两条消息被弹出的先后顺序不受保证因此断言只校验集合成员关系消息在超时后被删除util.sleep(timeout)后第三次q.pop()返回nil队列中已无消息空队列弹出返回nilwing 中的可选类型string \| undefined第三条是本用例的精华Queue.timeout在这里的真正作用是消息可见性/生命周期超时。在 tf-aws 平台它对应 SQS 的VisibilityTimeout消费者取走消息后若在超时内未处理完消息会重新可见在本用例中则被用来验证弹出即删除、超时后队列归空的行为。有趣的是这个测试文件在 sim 平台根本无法运行到test pop内部——因为new cloud.Queue(timeout: timeout)这行在 preflight 阶段就直接抛错了。这正是快照呈现1 unsupported的原因。为什么 sim 平台拒绝 timeout源码证据错误信息在 SDK 中确实存在见 target-sim/queue.ts 的构造函数constructor(scope: Construct, id: string, props: cloud.QueueProps {}) { super(scope, id, props); if (props.timeout) { throw new NotImplementedError( Queue.timeout is not supported on the sim platform yet., { issue: https://github.com/winglang/wing/issues/1980, resource: this.constructor.name, operation: timeout, }, ); } this.timeout props.timeout ?? Duration.fromSeconds(30); this.retentionPeriod props.retentionPeriod ?? Duration.fromHours(1); ... }关键信息sim 平台实现类Queue extends cloud.Queue即target-sim命名空间下的具体实现只要props.timeout被显式设置构造函数就抛出NotImplementedError并附带 GitHub issue 编号 1980 作为追踪链接For more information see那行正是该 issue 的渲染来源该限制仅存在于 sim 平台QueueProps.timeout是 cloud/queue.ts 中定义的抽象接口属性默认值 30ssim 实现只是暂未落地该能力sim 实现内部仍会读取timeout属性用于toSimulator()的 schema 传递与可见性超时逻辑pushMessagesBackToQueue中this.timeoutSeconds * 1000说明基础设施已预留只是显式传参尚未开放。同类限制在仓库中并非孤例tests/sdk_tests/queue/timeout.test.w顶部用/*\ skip: true \*/元注释整体跳过注释中直接引用同一 issue 1980tests/sdk_tests/queue/retention_period.main.w则用if target ! sim运行时条件把 timeout/retention 组合测试排除在 sim 之外。这形成了一个清晰的模式SDK 测试集中凡是触及 sim 尚不支持的能力要么用元注释跳过要么用目标平台条件分流。跨平台对照tf-aws 下 timeout 映射为 SQS VisibilityTimeout与 test 快照配对的是 compile 快照 pop.test.w_compile_tf-aws.md它记录了同一份pop.test.w在 tf-aws 平台编译生成的 Terraform 配置{ resource: { aws_sqs_queue: { Queue: { //: { metadata: { path: root/Default/Default/Queue/Default, uniqueId: Queue } }, message_retention_seconds: 3600, name: Queue-c822c726, visibility_timeout_seconds: 3 } } } }对照关系一目了然timeout: 3s→visibility_timeout_seconds: 3Queue.timeout在 AWS 平台被映射为 SQS 队列的可见性超时message_retention_seconds: 3600未显式设置retentionPeriod时采用默认值 1 小时3600 秒资源命名Queue-c822c726由资源命名规则生成80 字符上限、仅允许字母数字与-_见 target-tf-aws/queue.ts 的NAME_OPTS。tf-aws 实现 target-tf-aws/queue.ts 中visibilityTimeoutSeconds与messageRetentionSeconds的默认值逻辑与抽象接口保持一致30s / 1h因此同一份代码在不同平台编译会得到语义一致、实现不同的产物。这也是 hangar 快照体系的核心价值让跨平台行为差异显式化、可审查。pop() 的底层实现sim 随机抽取 vs AWS 原子删除pop()在 cloud/queue.ts 的抽象接口IQueueClient中定义为/** * Pop a message from the queue. * returns The message, or nil if the queue is empty. * inflight */ pop(): Promisestring | undefined;两种平台的实现体现了非 FIFO这一语义承诺的落地方式sim 平台target-sim/queue.inflight.ts队列在内存中用 JavaScriptArray承载pop()通过Math.random()随机下标splice取出消息天然满足非 FIFOpublic async pop(): Promisestring | undefined { return this.context.withTrace({ message: Pop ()., activity: async () { // extract a random message from the queue const message this.messages.splice( Math.floor(Math.random() * this.messages.length), 1, )[0]; return message?.payload; }, }); }AWS 平台shared-aws/queue.inflight.ts通过 SQS 的ReceiveMessageCommand取 1 条消息随即用DeleteMessageCommand删除依赖ReceiptHandle从而实现弹出即删除public async pop(): Promisestring | undefined { const receiveCommand new ReceiveMessageCommand({ QueueUrl: await this.queueUrl(), MaxNumberOfMessages: 1, }); const data await this.client.send(receiveCommand); if (!data.Messages || data.Messages.length 0) { return undefined; // 空队列返回 nil/undefined } const message data.Messages[0]; if (message.ReceiptHandle) { const deleteCommand new DeleteMessageCommand({ ... }); await this.client.send(deleteCommand); } return message.Body; }值得注意的是SQS 标准队列默认即是尽力而为的乱序队列与cloud.Queue默认非 FIFO 的抽象语义严格对应。若需要严格 FIFO需另行选用目标平台提供的有序队列能力——抽象层不保证顺序。快照是怎么生成的hangar 测试流水线该快照并非手写而是 hangarWing Toolchain Test Suite自动化生成并校验的产物。理解它的产生过程就能读懂快照中每一行的由来第一步生成测试描述文件。generate_tests.ts 递归扫描tests/sdk_tests目录下所有.w文件为每个文件生成一个 vitest 用例wing compile -t tf-aws和wing test -t sim各一个。pop.test.w因此有了两个测试目标与两个快照文件一一对应。第二步执行并收集输出。generated_test_targets.ts 中的testTest在临时目录运行wing test -t sim把进程的stdout写入fileMap[stdout.log]compileTest则运行wing compile -t tf-aws并把生成的main.tf.json及.wing目录下的 preflight/inflight 产物写入fileMap。第三步落盘快照。utils.ts 中的createMarkdownSnapshot把fileMap渲染成 Markdown首行标题携带源文件 | 用例类型 | 目标平台随后按文件扩展名用代码块包裹各产物。快照路径由 paths.ts 的snapshotDir决定即tools/hangar/__snapshots__。第四步对比校验。快照写入后后续每次运行测试都会与已提交的快照做toMatchFileSnapshot对比。若 SDK 行为、Terraform 产物或错误文案发生变化而快照未同步更新CI 会直接失败——这就是快照文件标题中源文件相对链接的用途方便开发者从快照一键跳回源测试文件核实。由于pop.test.w在 sim 平台因 timeout 限制无法运行到测试体testTest只收集到 stdout 中的报错日志因此快照只有stdout.log一节而 tf-aws 编译成功快照则包含完整的main.tf.json。1 unsupported / 1 skipped 的含义与工程启示快照末行的统计信息是 hangar 对平台能力不对称的显式登记Tests 1 unsupported (1)本文件的 1 个测试在 sim 平台不可用。根因是 preflight 阶段抛出的NotImplementedErrorwing 将其归类为平台未实现特性而非测试失败Snapshots 1 skipped未生成对应的成功快照避免把失败输出误当作基线Test Files 1 unsupported (1)整个文件在 sim 平台的测试目标被判定为不支持。这类unsupported快照与 unsupported.test.ts 中显式断言不支持资源须报错的测试共同构成 wing 的平台能力护栏抽象的cloud.*资源在各平台落地进度不同时必须以可预期的错误显式暴露而不是静默降级。对使用者而言这意味着在 sim 上调试队列类应用时应避免使用timeout参数若必须验证可见性超时行为可以参照tests/sdk_tests/queue/timeout.test.w的方式用target条件或元注释在平台间分流等待 issue 1980 落地。进一步阅读队列抽象与全部 inflight 方法cloud/queue.tssim 平台队列实现含 timeout 限制抛出点target-sim/queue.tssim 平台队列运行时随机 pop 与可见性超时回填target-sim/queue.inflight.tsAWS 平台队列实现SQS 映射target-tf-aws/queue.tsAWS 平台队列客户端SQS 原子 popshared-aws/queue.inflight.ts队列官方参考文档cloud/queue.md其余队列测试用例tests/sdk_tests/queue/下的push.test.w、purge.test.w、timeout.test.w、retention_period.main.w等文件赞分享编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载相关推荐深入解析 Wing 云队列 retentionPeriod从 Hangar 测试快照到 SDK 多平台实现深入解析 Wing 云队列 retentionPeriod从 Hangar 测试快照到 SDK 多平台实现 Wing 语言中的 cloud.Queue 是面向编程语言编译器云原生语言运行时Wing 云语言 math 标准库 fibonacci 函数实战从递归实现到 sim 平台测试快照验证Wing 云语言 math 标准库 fibonacci 函数实战从递归实现到 sim 平台测试快照验证 导读 本文以 Wing 仓库中 fibonacci.t编程语言编译器云原生语言运行时Wing 语言 cloud.Queue push 操作实战从 SDK 源码到 hangar 快照测试sim 平台Wing 语言 cloud.Queue push 操作实战从 SDK 源码到 hangar 快照测试sim 平台 Wing 是一门面向云的应用编程语言编程语言编译器云原生语言运行时创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考