feat(sftp): add connection pool to SFTP storage driver - #392
Conversation
- 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
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughSFTP 驱动改为连接池复用:新增租约、空闲回收和错误后复用判定;各存储操作统一改为从池中获取连接并归还。集成测试切换了容器镜像、端口和启动参数,并补充连接池断言;中英文测试文档同步更新。 ChangesSFTP 连接池化
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 时归还或丢弃
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
developer-docs/en/testing.mddeveloper-docs/zh-CN/testing.mdsrc/storage/drivers/sftp.rstests/test_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
|
@coderabbitai review |
✅ Action performedReview finished.
|
SftpConnectionPoolwith a semaphore-based size limit (default 4) and idle connection reuse viaMutex<Vec<IdleSftpConnection>>SftpConnectionLeaseRAII guard that returns connections to the pool on drop when marked reusable, discards on erroris_sftp_connection_reusable_after_errorto distinguish recoverable SFTP status errors from connection-loss errorsconnect()calls withacquire_connection()across allStorageDriverandStreamUploadDrivermethodsdebug_connection_pool_snapshot()under#[cfg(debug_assertions)]for integration test assertionsatmoz/sftptolscr.io/linuxserver/openssh-serverwith env-var configurationClosed #390
Summary by CodeRabbit