Skip to content

fix(webdav): 删除文件/目录时按引用计数回收共享缩略图 - #87

Merged
fanchenggang merged 1 commit into
mainfrom
fix/thumbnail-refcount
Sep 6, 2026
Merged

fix(webdav): 删除文件/目录时按引用计数回收共享缩略图#87
fanchenggang merged 1 commit into
mainfrom
fix/thumbnail-refcount

Conversation

@fanchenggang

Copy link
Copy Markdown
Owner

对应上游 issue longern/FlareDrive#16(已在 上游认领 并提交 上游 PR longern/FlareDrive#43),本 PR 将同一修复移植到 Davflare 的 functions/webdav/protocol.ts

问题

缩略图按内容摘要寻址(_$flaredrive$/thumbnails/<digest>.png)并被内容相同的文件共享,而 handleDelete / deleteAll 从不清理缩略图 → 删除图片后缩略图永远残留。本地代码与上游存在同样的问题。

方案:per-path 引用 marker(无计数器、无读改写)

每个引用文件在 _$flaredrive$/thumbnails/refs/<digest>/<path> 保留一个不可变 marker 对象,引用清零才回收缩略图。所有操作都是单对象 PUT/DELETE,无读改写竞争:并发删除最坏只会多留(与现状一致的良性泄漏),不会误删仍在使用的缩略图。

操作 行为
PUT / 分片创建 / COPY 写目标对象先写 marker
PUT 后校验 缩略图本体缺失(被并发回收)→ 409,客户端整体重试
DELETE(文件) 删文件 → 删 marker → 引用清零则回收缩略图
DELETE(目录) 逐个移除子项 marker,按 digest 去重后统一回收
DELETE /webdav/(全删) 连带清空 internal 缩略图子树(deleteAll 本身会跳过 internal 前缀)
覆盖写入 fd-thumbnail 变化时释放旧引用;未带头时保留原 metadata(Davflare 既有语义,引用仍有效)
MOVE 先补目标引用再释放源引用,移动全程缩略图始终有引用覆盖

另外 fd-thumbnail 头现在按 hex 摘要格式(16–128 位)校验后才进入 R2 key。

兼容性

  • 历史缩略图没有 marker → 保守保留(宁可多留,不误删共享缩略图);重写引用文件或全删后自然收敛
  • 第三方 WebDAV 客户端的 COPY/MOVE 也能正确同步引用(复制的是带 thumbnail 的 customMetadata)

测试

  • 新增 src/app/__tests__/webdavThumbnailGc.test.ts:11 项场景(建引用/共享/最后引用回收/覆盖释放/保留语义/目录删除/全删/COPY/MOVE/分片/非法头防护)
  • webdavProtocol.test.ts 的 PUT 覆盖用例改用合法 hex 摘要并补齐缩略图本体 seed(对齐真实客户端时序)
  • 全量 918 测试通过,tsc --noEmit 干净

缩略图按内容摘要寻址并被内容相同的文件共享,原删除逻辑从不清理
_$flaredrive$/thumbnails/,孤儿缩略图无限累积。每个引用文件现在在
_$flaredrive$/thumbnails/refs/<digest>/<path> 保留不可变 marker 对象:

- PUT / 分片创建 / COPY 先写 marker 再写引用对象,并发删除不会误收
  还在上传中的缩略图;PUT 后校验缩略图本体存在,缺失时 409 让客户端重试
- DELETE(文件/目录)先移除 marker,引用清零才回收缩略图;目录删除按
  digest 去重回收;全删(DELETE /webdav/)连带清空 internal 缩略图子树
- 覆盖写入(fd-thumbnail 变化)释放旧引用;MOVE 先补目标引用再释放源引用
- fd-thumbnail 头按 hex 摘要格式校验后才进入 R2 key

兼容性:历史缩略图无 marker 时保守保留(宁可多留不误删);未带
fd-thumbnail 的覆盖仍保留原 customMetadata(Davflare 既有语义)。

同步上游修复 longern/FlareDrive#43,测试 11 项(webdavThumbnailGc),
全量 918 测试通过。
@fanchenggang
fanchenggang merged commit 5676c66 into main Sep 6, 2026
3 checks passed
@fanchenggang
fanchenggang deleted the fix/thumbnail-refcount branch September 6, 2026 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant