Skip to content

Latest commit

 

History

History
204 lines (162 loc) · 6.08 KB

File metadata and controls

204 lines (162 loc) · 6.08 KB

Rebase兼容性分析报告

提交概览

共引入 21个commits,主要涉及以下模块:

核心功能改动

1. 链接刷新机制 (internal/stream/util.go)

Commits:

  • 4c33ffa4 feat(link): add link refresh capability for expired download links
  • f38fe180 fix(stream): 修复链接过期检测逻辑,避免将上下文取消视为链接过期
  • 7cf362c6 fix(stream): 更新过期链接检查逻辑,支持所有4xx客户端错误
  • 03fbaf1c refactor(stream): 移除过时的链接刷新逻辑,添加自愈读取器以处理0字节读取

核心代码:

// 新增常量
MAX_LINK_REFRESH_COUNT = 50    // 链接最大刷新次数
MAX_RANGE_READ_RETRY_COUNT = 5 // RangeRead重试次数(从3提升到5)

// 新增函数
IsLinkExpiredError(err error) bool  // 判断是否为链接过期错误

// 新增结构
RefreshableRangeReader struct {
    link         *model.Link
    size         int64
    innerReader  model.RangeReaderIF
    mu           sync.Mutex
    refreshCount int  // 防止无限循环
}

selfHealingReadCloser struct {
    // 检测0字节读取,自动刷新链接
}

功能说明:

  1. 链接过期检测: 识别多种云盘的过期错误(expired, token expired, access denied, 4xx状态码等)
  2. 自动刷新: 检测到过期时自动调用Refresher获取新链接,最多刷新50次
  3. 自愈机制: 处理某些云盘返回200但内容为空的情况(0字节读取检测)
  4. 并发安全: 使用sync.Mutex保护共享状态
  5. Context隔离: 刷新时使用WithoutCancel避免用户取消操作影响刷新

潜在风险:

  • ✅ Context.WithoutCancel需要Go 1.21+
  • ✅ 并发场景下的锁竞争
  • ✅ refreshCount可能在某些场景下不递增导致无限循环

2. 目录预创建优化 (internal/fs/copy_move.go)

Commit: ce0da112 fix(copy_move): 将预创建子目录的深度从2级调整为1级

核心代码:

func (t *FileTransferTask) preCreateDirectoryTree(objs []model.Obj, dstBasePath string, maxDepth int) error {
    // 第一轮:创建直接子目录
    for _, obj := range objs {
        if obj.IsDir() {
            subdirPath := stdpath.Join(dstBasePath, obj.GetName())
            op.MakeDir(t.Ctx(), t.DstStorage, subdirPath)
            subdirs = append(subdirs, obj)
        }
    }
    
    // 停止递归条件
    if maxDepth <= 0 {
        return nil
    }
    
    // 第二轮:递归创建嵌套目录
    for _, subdir := range subdirs {
        subObjs := op.List(...)
        preCreateDirectoryTree(subObjs, subdirDstPath, maxDepth-1)
    }
}

功能说明:

  1. 深度控制: 默认maxDepth=1,只预创建2级目录(当前+子级)
  2. 防止深度递归: 避免在大型项目中递归过深导致栈溢出或性能问题
  3. 错误容忍: MakeDir失败时继续处理其他目录
  4. Context感知: 每次循环检查ctx.Err()支持取消操作

潜在风险:

  • ✅ op.MakeDir和op.List调用需要存储初始化
  • ✅ 大量目录时的性能问题
  • ✅ Context取消时的资源清理

3. 网络优化 (drivers/, internal/net/)

Commits:

  • b9dafa65 feat(network): 增加对慢速网络的支持,调整超时和重试机制
  • bce47884 fix(driver): 增加夸克分片大小调整逻辑,支持重试机制
  • 0b8471f6 feat(quark_open): 添加速率限制和重试逻辑

功能说明:

  1. 提升RangeRead重试次数: 3 → 5
  2. 调整网络超时参数
  3. 添加分片上传重试逻辑

4. 驱动修复

Commits:

  • da2812c0 fix(google_drive): 更新Put方法以支持可重复读取流和不可重复读取流的MD5校验
  • 5a6bad90 feat(google_drive): 添加文件夹创建的锁机制和重试逻辑
  • a54b2388 feat(google_drive): 添加处理重复文件名的功能
  • 9ef22ec9 fix(driver): fix file copy failure to 123pan due to incorrect etag
  • 0ead87ef fix(alias): update storage retrieval method in listRoot function
  • 311f6246 fix: 修复500 panic和NaN问题

兼容性评估

✅ 编译兼容性

  • 构建成功,无语法错误
  • 依赖版本无冲突

✅ API兼容性

  • 新增函数不破坏现有接口
  • RefreshableRangeReader实现model.RangeReaderIF接口
  • 向后兼容旧代码

⚠️ 运行时兼容性

需要验证的场景:

  1. 并发安全: RefreshableRangeReader的并发读取
  2. 资源泄漏: Context取消时goroutine是否正确退出
  3. 边界条件:
    • refreshCount达到50次的行为
    • 0字节读取检测的准确性
    • maxDepth=0时的目录创建
  4. 错误处理:
    • nil Refresher时的处理
    • 链接刷新失败时的回退机制
  5. 性能:
    • 大文件下载时的刷新开销
    • 深层目录结构的预创建性能

测试需求

必须测试的场景

Stream包测试

  1. IsLinkExpiredError准确性

    • 各种云盘的过期错误格式
    • Context取消不应判断为过期
    • HTTP 4xx/5xx的区分
  2. RefreshableRangeReader可靠性

    • 正常读取流程
    • 自动刷新触发和成功
    • 达到最大刷新次数
    • 并发读取安全性
    • Context取消的正确处理
  3. selfHealingReadCloser

    • 0字节读取检测
    • 刷新重试机制
    • 资源正确关闭

FS包测试

  1. preCreateDirectoryTree
    • 深度控制正确性(0, 1, 2级)
    • 大量目录的性能
    • Context取消的响应
    • 错误容忍性

风险等级: 中等

原因:

  • ✅ 新功能设计合理,有明确的边界和错误处理
  • ⚠️ 并发场景需要充分测试
  • ⚠️ 链接刷新逻辑复杂,需要验证各种边界情况
  • ⚠️ 依赖op包的函数需要正确的初始化

推送建议: 通过测试后可推送

前置条件:

  1. 完成全面的单元测试(见下方测试代码)
  2. 验证并发安全性
  3. 确认Context取消不会导致资源泄漏
  4. 性能测试通过(大文件、深层目录)

建议测试命令:

# 单元测试
go test ./internal/stream ./internal/fs -v -count=1 -race

# 压力测试
go test ./internal/stream -run Stress -v -count=10

# 完整测试套件
go test ./... -short -count=1