Skip to content

finding(objectql): Archiver 的 20 批循环不看 #4747 的 abort 位 —— teardown 期间仍会继续读写正在关闭的 datasource #5755

Description

@os-zhuang

观察类 finding,来自 #5194 / PR #5753 的实现。今天没有用户会撞到,记录在案由 PM 定级。

事实(origin/main + PR #5753)

LifecycleService 的 #4747 契约是「stop() 抬起 abort 位,sweep 在每个 leg boundary 检查」。目前检查点有两处:

archiveObject() 的批量循环(:1047,for (let batch = 0; batch < ARCHIVE_MAX_BATCHES_PER_SWEEP; batch++))没有这个检查。一轮 archive 最多 20 批 × 500 行,每批是 hot.find + 每行一次 cold.upsert + 一次 hot.bulkDelete —— 即最多一万次跨两个 datasource 的写。stop() 在其中任何一点落下,循环都会把剩余批次跑完。

这正是 #4747 描述的形状:「a sweep already in flight would keep reading and deleting through an engine whose datasource the host is closing underneath it — the reads fail as Unable to acquire a connection」。reap 那一侧已经补上,archive 这一侧没有。

为什么现在不会有人撞到

  • archive 策略要求已配置 cold datasource(archive.to),未配置时 archiveObject 直接 skipped: 'archive-pending' 返回,一行都不搬;
  • 目前仓库里没有平台对象声明 archive(声明 lifecycle 的 11 个对象走的是 retention/ttl);
  • 触发条件还要叠加「teardown 恰好落在一次大批量归档中途」。

所以这是一条为将来第一个真声明 archive 的部署准备的洞,不是当下的故障。

修法

与 :1202 同款一行:循环体开头 if (this.abort.aborted) break;。注意 archive 的安全规则是「归档成功才热删」,按批 break 不破坏它 —— 每批的 upsert→bulkDelete 已经成对完成,未开始的批次留给下一轮。

Found-during: #5194 / PR #5753

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions