Skip to content

finding(objectql): archive 的冷侧 keep prune 在 abort 位已抬起后仍发一次 DELETE —— 循环之后的那条腿没跟上 #4747 #5966

Description

@baozhoutao

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

事实(origin/main + PR #5956)

PR #5956 给 archiveObject() 的批循环补上了 #4747 的 abort 检查(与 batchedReap 同款)。补完之后,archiveObject() 里循环之后还剩一条腿没有该检查 —— 冷侧 keep 保留期的 prune:

// (批循环在此 break —— 此时 this.abort.aborted 已确定为 true)

// Cold-side retention: `keep` bounds the archive itself.
if (archive.keep && typeof cold.deleteMany === 'function') {
  const keepCutoff = new Date(this.now() - parseLifecycleDuration(archive.keep)).toISOString();
  await cold.deleteMany(object, { where: { created_at: { $lt: keepCutoff } } });
}

于是 teardown 落在批循环中途时:循环按新检查停下,紧接着仍会向正在关闭的 cold datasource 发一次谓词 DELETE。

为什么值得单独记一条(而不是「单次 await,可接受」)

这与 #5194 之前「无 guard reap 是两个检查点之间的单个 await」的形态不同,差别在于代码是否已经知道答案:

为什么现在不会有人撞到

三重叠加,比 #5755 还窄:

  • archive 策略要求已配置 cold datasource(archive.to),未配置直接 skipped: 'archive-pending';
  • 还要求显式声明 archive.keep(未声明则整条腿不执行);
  • 目前仓内没有平台对象声明 archive,更没有声明 keep。

修法(一行,若 PM 认为该修)

把该腿并入同一个判定即可,例如 if (!this.abort.aborted && archive.keep && typeof cold.deleteMany === 'function'),或在其前加一行早退。语义上不存在取舍:cold prune 是纯保留期回收,推迟到下一轮 sweep 无任何副作用(它不像热删那样受「归档成功才热删」的配对约束)。

PR #5956 未顺手改:该 PR 的裁定范围是批循环那一行,且其测试 fixture 有意不声明 keep,以免断言一条本 PR 不治理的腿。

Found-during: #5755 / PR #5956

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