feat(server/s3): support multipart upload#2813
Draft
xrgzs wants to merge 3 commits into
Draft
Conversation
Replace itsHenry35/gofakes3 with OpenListTeam/gofakes3 Signed-off-by: MadDogOwner <xiaoran@xrgzs.top>
- Implement gofakes3 MultipartBackend (Create/UploadPart/Complete/Abort) on s3Backend so multipart parts stream to local temp files instead of being buffered in memory - Track in-progress uploads via a new uploads sync.Map on s3Backend - Refactor the PutObject body into a reusable putStream helper shared with the multipart Complete path - Validate part ordering, etags and existence, reject short reads, and return S3-style multipart etags - Add end-to-end multipart tests against a real Local driver Co-authored-by: Codex <267193182+codex@users.noreply.github.com>
- Track lastActivity on each multipart upload, updated on create and every part upload, so idle uploads can be detected - Add a background reaper per backend instance that removes uploads inactive for longer than the TTL (default 24h) and cleans their temp directories - Add a startup sweep that removes leftover s3-multipart-* directories older than the TTL, recovering part files from a previous crash - Add a configurable s3.multipart_ttl (env S3_MULTIPART_TTL) duration, parsed via time.ParseDuration with a 24h default - Add tests for TTL-based reaping and stale-directory cleanup Co-authored-by: Codex <267193182+codex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 摘要
为 fake S3 服务器实现分片上传(multipart upload)支持,并自动回收被遗弃的分片上传。本 PR 含三个提交:
refactor(server/s3): use OpenListTeam/gofakes3-- 将依赖从github.com/itsHenry35/gofakes3 v0.0.8切换到github.com/OpenListTeam/gofakes3 v0.8.0。旧版只有把所有分片缓存在内存的默认上传器;OpenListTeam fork 新增了可选的MultipartBackend接口,允许后端自行流式处理分片,这是实现分片上传的前提。同步更新server/s3下 8 个文件的 import 路径。feat(server/s3): support multipart upload-- 在s3Backend上实现gofakes3.MultipartBackend,把分片上传四个操作(Initiate / UploadPart / Complete / Abort)路由到 OpenList 自有后端:每个分片流式写入本地临时文件,完成时按分片号顺序拼合并写入底层存储。feat(server/s3): reap abandoned multipart uploads-- 回收被遗弃的分片上传,避免临时文件无限累积。为什么需要:此前分片上传回退到 gofakes3 默认的内存上传器,会把每个分片都缓存在内存中,大文件分片上传可能耗尽内存;且客户端不 complete/abort 的孤儿上传会一直占用磁盘。现在改为按分片落盘(内存占用恒定),并由后台 reaper 自动清理超时未活动的上传。
用户可感知的行为变化:S3 客户端(awscli / s3cmd / rclone 等)的分片上传现在可用,不再因内存限制而失败;被遗弃的分片上传会在 TTL 后被自动回收。
重要实现变化:
OpenListTeam/gofakes3 v0.8.0(baseBackend接口兼容,既有单分片PutObject等行为不变)server/s3/multipart.go,实现gofakes3.MultipartBackend(CreateMultipartUpload / UploadPart / CompleteMultipartUpload / AbortMultipartUpload)s3Backend新增uploads sync.Map跟踪进行中的上传;每个上传记录lastActivity,在创建与每次分片上传时更新PutObject主体抽取为可复用的putStream,与分片 Complete 路径共享(目录创建、元数据、忽略规则一致);单分片PutObject行为不变conf.Conf.TempDir下的s3-multipart-*目录;返回 S3 规范的分片 etag("<md5ofmd5s>-N")ErrIncompleteBody;abort 幂等;Complete 失败时保留上传以便客户端重试TTL/4(钳制[10s, 1h])间隔回收lastActivity超过 TTL 的上传及其临时目录;启动时额外清理上次进程崩溃残留的s3-multipart-*目录(仅清理超过 TTL 的,避免误伤并发启动的兄弟实例)s3.multipart_ttl(envS3_MULTIPART_TTL),用time.ParseDuration解析,空/非法/<=0 回退默认24h配置/存储/API/兼容性:新增一个可选配置项
s3.multipart_ttl(默认 24h,不配置即用默认值);不修改已有 API、存储格式或迁移行为。This PR has breaking changes.
/ 此 PR 包含破坏性变更。
This PR changes public API, config, storage format, or migration behavior.
/ 此 PR 修改了公开 API、配置、存储格式或迁移行为。
This PR requires corresponding changes in related repositories.
/ 此 PR 需要关联仓库同步修改。
Related repository PRs / 关联仓库 PR:
Related Issues / 关联 Issue
Related to #460
Testing / 测试
go test ./...执行过的命令与结果(平台:macOS arm64,Go 1.26.5):
go build ./server/s3/、go build ./server/、go build ./internal/conf/-- 通过go vet ./server/...、go vet ./internal/conf/-- 干净gofmt -l server/s3/*.go internal/conf/config.go-- 干净go test ./server/s3/ -count=1-- 通过,包含新增测试:TestMultipartUploadEndToEnd:在真实 Local 驱动上 create->3 分片->complete,校验落盘文件内容为拼接结果、etag 为"<hex>-3";同号重传覆盖;短读->ErrIncompleteBody;未知 upload->ErrNoSuchUpload;越界分片号->ErrInvalidPart;乱序->ErrInvalidPartOrder;错 etag->ErrInvalidPart;缺分片->ErrInvalidPart;失败的 complete 保留上传可重试TestMultipartAbort:abort 删除临时目录并移除记录,且对未知 upload 幂等TestMultipartReapExpired:lastActivity超过 TTL 的上传被回收且临时目录删除,活跃上传保留TestMultipartCleanupStaleDirs:超过 TTL 的s3-multipart-*残留目录被清理,新目录保留go test ./...:server/s3通过。其余失败均与本次改动无关且为环境/既有问题--pkg/aria2/rpc:需连接localhost:6800的 aria2 守护进程(本机禁网)drivers/teldrive、drivers/webdav:需外部服务器/凭据internal/netTestNewOSSClientUsesEnvironmentHTTPSProxy:仓库既有失败(expected *http.Transport, got *net.safeTransport)drivers/*、internal/offline_download/*的 build failed:并行go test ./...时模块缓存写入竞争所致,单独go build正常server/s3(仅server/s3.go导入),不受本次改动影响未执行:对运行中的 OpenList 实例用 awscli / rclone 做手动联调(如维护者需要可补)。
Checklist / 检查清单
/ 我已阅读 CONTRIBUTING。
/ 我确认此贡献符合仓库许可证、贡献规范和行为准则。
gofmt,go fmt, orprettierwhere applicable./ 我已按适用情况使用
gofmt、go fmt或prettier格式化变更代码。/ 我已在适用情况下请求相关维护者或代码所有者审查。
AI Disclosure / AI 使用声明
/ 此 PR 包含 AI 辅助内容。
Tools used / 使用工具:
Usage scope / 使用范围:
Code generation / 代码生成
Refactoring / 重构
Documentation / 文档
Tests / 测试
Translation / 翻译
Review assistance / 审查辅助
I have reviewed and validated all AI-assisted content included in this PR.
/ 我已审核并验证此 PR 中的所有 AI 辅助内容。
I have ensured that all AI-assisted commits include
Co-Authored-Byattribution./ 我已确保所有 AI 辅助提交都包含
Co-Authored-By归属信息。I can reproduce all AI-assisted content included in this PR without any AI tools.
/ 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。
Known Limitations / 已知限制
conf.Conf.TempDir,大文件上传会占用等量本地磁盘(相对原内存缓冲已是改进,为流式后端的固有取舍)。