Skip to content

feat(sftp): add connection pool to SFTP storage driver - #392

Merged
AptS-1547 merged 2 commits into
masterfrom
feat/issue-390-sftp-connect-pool
Jul 7, 2026
Merged

feat(sftp): add connection pool to SFTP storage driver#392
AptS-1547 merged 2 commits into
masterfrom
feat/issue-390-sftp-connect-pool

Conversation

@AptS-1547

@AptS-1547 AptS-1547 commented Jul 7, 2026

Copy link
Copy Markdown
Member
  • Introduce SftpConnectionPool with a semaphore-based size limit (default 4) and idle connection reuse via Mutex<Vec<IdleSftpConnection>>
  • Add SftpConnectionLease RAII guard that returns connections to the pool on drop when marked reusable, discards on error
  • Add is_sftp_connection_reusable_after_error to distinguish recoverable SFTP status errors from connection-loss errors
  • Replace per-operation connect() calls with acquire_connection() across all StorageDriver and StreamUploadDriver methods
  • Expose debug_connection_pool_snapshot() under #[cfg(debug_assertions)] for integration test assertions
  • Switch integration test container from atmoz/sftp to lscr.io/linuxserver/openssh-server with env-var configuration
  • Add pool-aware integration test assertions verifying connection reuse, idle count, and stream lease isolation
  • Add unit tests for pool size lower bound, timeout constant values, and connection reusability classification
  • Update developer docs (en + zh-CN) to reference the new container image

Closed #390

Summary by CodeRabbit

  • 新功能
    • SFTP 存储操作现支持连接复用(含流式读取占用连接语义),提升连续上传、下载与读取的稳定性与效率。
  • 改进/修复
    • 对特定失败场景增加更安全的连接复用策略,避免将无效连接用于后续操作。
  • 文档
    • 更新 SFTP 集成测试文档与默认测试容器镜像/端口配置。

- Introduce `SftpConnectionPool` with a semaphore-based size limit (default 4) and idle connection reuse via `Mutex<Vec<IdleSftpConnection>>`
- Add `SftpConnectionLease` RAII guard that returns connections to the pool on drop when marked reusable, discards on error
- Add `is_sftp_connection_reusable_after_error` to distinguish recoverable SFTP status errors from connection-loss errors
- Replace per-operation `connect()` calls with `acquire_connection()` across all `StorageDriver` and `StreamUploadDriver` methods
- Expose `debug_connection_pool_snapshot()` under `#[cfg(debug_assertions)]` for integration test assertions
- Switch integration test container from `atmoz/sftp` to `lscr.io/linuxserver/openssh-server` with env-var configuration
- Add pool-aware integration test assertions verifying connection reuse, idle count, and stream lease isolation
- Add unit tests for pool size lower bound, timeout constant values, and connection reusability classification
- Update developer docs (en + zh-CN) to reference the new container image

Closed #390
@AptS-1547 AptS-1547 self-assigned this Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f96a433-be59-446c-9776-7c64ff5e4e01

📥 Commits

Reviewing files that changed from the base of the PR and between fcadbb8 and 1d5a934.

📒 Files selected for processing (2)
  • src/storage/drivers/sftp.rs
  • tests/test_sftp.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_sftp.rs
  • src/storage/drivers/sftp.rs

📝 Walkthrough

Walkthrough

SFTP 驱动改为连接池复用:新增租约、空闲回收和错误后复用判定;各存储操作统一改为从池中获取连接并归还。集成测试切换了容器镜像、端口和启动参数,并补充连接池断言;中英文测试文档同步更新。

Changes

SFTP 连接池化

Layer / File(s) Summary
连接池类型与常量
src/storage/drivers/sftp.rs
引入连接池所需的并发与时间原语,补充池化常量,并在 SftpDriver 中新增池字段;定义连接池、空闲连接、租约和快照结构。
连接池生命周期
src/storage/drivers/sftp.rs
实现连接池获取、空闲回收、创建计数、快照输出和租约归还逻辑,并在读取器错误时丢弃租约。
初始化与连接入口
src/storage/drivers/sftp.rs
SftpDriver::new 创建默认连接池,新增调试快照与连接获取入口,并拆分新建连接逻辑。
存储操作接入租约
src/storage/drivers/sftp.rs
open_readerputgetdeleteexistsmetadatacopy_objectput_reader 改为通过连接池获取租约连接,并在成功后标记可复用。
复用判定与单元测试
src/storage/drivers/sftp.rs
新增错误后连接可复用判定函数,并扩展单元测试覆盖默认池大小、下界处理和不同状态码的复用结果。
集成测试与文档
tests/test_sftp.rs, developer-docs/en/testing.md, developer-docs/zh-CN/testing.md
集成测试切换容器镜像、端口、环境变量、探测超时和基础路径,并补充连接池快照断言;中英文测试文档同步更新镜像说明。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SftpDriver
  participant SftpConnectionPool
  participant SftpConnectionLease
  participant SftpSession

  SftpDriver->>SftpConnectionPool: acquire_connection()
  SftpConnectionPool-->>SftpDriver: lease
  SftpDriver->>SftpSession: 执行 put/get/delete/metadata
  alt 操作成功
    SftpDriver->>SftpConnectionLease: mark_reusable()
  else 读取错误
    SftpDriver->>SftpConnectionLease: discard()
  end
  SftpConnectionLease->>SftpConnectionPool: Drop 时归还或丢弃
Loading

Possibly related PRs

Suggested labels: Enhancement, Rust, Storage Driver

Poem

旧连接别再一把梭,
池里租约转一圈。
读写删查都走这条线,
错了就丢,干净利落。
🐾 48看着,别乱来。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning 描述包含了变更摘要和测试点,但没有按模板提供 Summary、Test plan、Notes for reviewers 等必填结构。 按模板补齐 Summary、Test plan 和 Notes for reviewers,小节用清晰条目说明相关测试、配置变化和审阅注意事项。
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了本次核心变更:为 SFTP 存储驱动引入连接池。
Linked Issues check ✅ Passed 实现与 #390 目标一致:连接池复用、租约语义、流式读取持有租约、错误后丢弃失效连接和补充测试都已覆盖。
Out of Scope Changes check ✅ Passed 未见明显超出 #390 目标的改动,文档、测试和容器镜像调整都服务于连接池重构。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-390-sftp-connect-pool

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AptS-1547

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_sftp.rs (1)

10-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

建议给测试容器镜像钉版本号,别用 latest

SFTP_TAG 从原来的 alpine 改成了浮动标签 latest。集成测试容器用 latest 意味着上游镜像随时可能悄悄变了行为(环境变量默认值、启动顺序、host key 生成时机等),届时 CI 说炸就炸,你都不知道是谁的锅。钉一个具体版本 tag 更稳。

♻️ 建议
-const SFTP_TAG: &str = "latest";
+const SFTP_TAG: &str = "<pin-a-specific-version>";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_sftp.rs` around lines 10 - 11, The SFTP test container is
currently pinned to a floating `latest` tag, so update the SFTP image versioning
in the `SFTP_IMAGE` and `SFTP_TAG` constants within `test_sftp.rs` to use a
specific immutable release tag instead. Keep the test using the same image
source, but replace the mutable tag with a concrete version so the integration
test behavior remains stable across CI runs and upstream changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/storage/drivers/sftp.rs`:
- Around line 939-946: 将 is_sftp_connection_reusable_after_error
的判定从“排除少数错误”改为“仅允许白名单状态复用”,避免 BadMessage
等协议级异常的连接被重新放回池中继续污染后续请求;请在该函数及其调用链对应的测试中按白名单方式收紧可复用条件,并补充 BadMessage 和其他非白名单
Status 不可复用的单元测试,确保只把明确安全的错误类型视为可复用。

---

Nitpick comments:
In `@tests/test_sftp.rs`:
- Around line 10-11: The SFTP test container is currently pinned to a floating
`latest` tag, so update the SFTP image versioning in the `SFTP_IMAGE` and
`SFTP_TAG` constants within `test_sftp.rs` to use a specific immutable release
tag instead. Keep the test using the same image source, but replace the mutable
tag with a concrete version so the integration test behavior remains stable
across CI runs and upstream changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e5bf2640-673a-44c1-a6b4-23e3639a9f1c

📥 Commits

Reviewing files that changed from the base of the PR and between 0b2ba87 and fcadbb8.

📒 Files selected for processing (4)
  • developer-docs/en/testing.md
  • developer-docs/zh-CN/testing.md
  • src/storage/drivers/sftp.rs
  • tests/test_sftp.rs

Comment thread src/storage/drivers/sftp.rs
…s codes

Change connection reuse logic from denylisting connection errors to allowlisting only known-safe status codes (NoSuchFile, PermissionDenied). This prevents potential connection corruption from unexpected error types.

Changes:
- Refactor `is_sftp_connection_reusable_after_error()` to use allowlist approach
- Only reuse connections for NoSuchFile and PermissionDenied status codes
- Add test coverage for BadMessage, Failure, OpUnsupported, and NoConnection codes
- Rename test to reflect new allowlist-based behavior
- Pin SFTP test container image to specific version (10.2_p1-r0-ls229) for stability
@AptS-1547

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@AptS-1547
AptS-1547 merged commit 549fa79 into master Jul 7, 2026
4 of 7 checks passed
@AptS-1547
AptS-1547 deleted the feat/issue-390-sftp-connect-pool branch July 7, 2026 10:01
@AptS-1547
AptS-1547 restored the feat/issue-390-sftp-connect-pool branch July 7, 2026 18:14
@AptS-1547
AptS-1547 deleted the feat/issue-390-sftp-connect-pool branch July 7, 2026 18:14
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.

Optimize SFTP driver connection reuse

1 participant