GCWing / GCWing/OpenBitFun

[Bug] Remote SSH workspace: Write/Edit permanently fail with "Limit exceeded: handle limit reached" after long session (russh-sftp client-side handle leak)

Offen
#2,424 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Rust
Sterne
2.2k
Forks
229
Ø Merge
2 Std. 46 Min.
Gemergte PRs (30 T.)
577

Beschreibung

### Summary

远程 SSH 工作区在长会话高强度使用文件工具后,所有 `Write`/`Edit` 持续失败,报 `Limit exceeded: handle limit reached`,等待 30 分钟以上不自愈,只能重启桌面端恢复。同期 `Read`/`Glob`/`Grep`/终端均正常。

定位证据指向 russh-sftp 客户端侧句柄表泄漏(见下)。

### Area

Desktop app

### Reproduction or evidence

1. 连接远程 SSH 工作区,长时间高频使用文件工具(大量分块 Read、多次 Write/Edit);
2. 累计足够多打开/关闭循环后触发;
3. 此后所有 `Write`/`Edit` 持续失败,间隔 30 分钟以上的多次重试均不恢复;
4. `Read`/`Glob`/`Grep`/`ExecCommand` 全部正常。

`Write`:

```
Tool 'Write' failed (execution_error): Tool error: Failed to write file:
Failed to create remote file '/path/to/workspace/.bitfun/tmp/write_xxxxxxxx.tmp':
Limit exceeded: handle limit reached
```

`Edit`(内置 re-read 步骤即失败):

```
File /path/to/file.py could not be re-read before editing
(Tool error: Failed to read file: Failed to open remote file '/path/to/file.py':
Limit exceeded: handle limit reached)
```

注意不对称性:普通 `Read` 工具同一时刻仍能成功打开同一文件,而 `Edit` 内部 re-read 与 `Write` 的新建 open 失败——疑似读/写两条 SFTP 会话中写路径的句柄表先耗尽。

1. `handle limit reached` 错误串在 bitfun-desktop 二进制 strings 中与 `russh_sftp::client::rawsession`、`attempt to close more handles than exist` 相邻——错误来自 **russh-sftp 客户端侧会话句柄表**,不是服务端 sshd(远端 sftp-server 进程仅 7 个 fd,远未达任何限制)。
2. 上游生态已确认同类机制:remotefs-rs-ssh PR#22(https://github.com/remotefs-rs/remotefs-rs-ssh/pull/22)原文:

> russh-sftp's `File::drop` closes handles via `close_nowait`, which frees the handle server-side but never decrements the client's open-handle counter. Reads (one handle per chunk) and writes (one handle per upload) relied on `Drop`, so the counter climbed monotonically until the negotiated limit was reached, failing later operations with `Limit exceeded: Handle limit reached`.

与本例现象逐点吻合:计数单调增长、达到协商上限后新 open 全失败、不自愈。

- SFTP 文件句柄关闭使用 awaited close/shutdown(等 close 响应后再递减客户端计数器),不依赖 `Drop`/`close_nowait`;
- 读路径若按 chunk 开关 handle,考虑单 handle + seek 复用;
- 收到 `Handle limit reached` 时自动重建 SFTP 会话(句柄表随会话重置)实现自愈,而不是让错误永久驻留;
- 建议在日志中输出 open-handle 计数与上限,便于确认泄漏速率。

### Environment, if relevant

- BitFun 桌面端 **0.2.18**(macOS,Tauri/Rust 后端)
- 工作区类型:**Remote SSH**(目标 macOS 主机,OpenSSH + sftp-server)
- 桌面进程连续运行 1 天 9 小时+;触发前约 1.5~2 小时高强度使用(数十次大文件分块 Read + 若干次 Write/Edit)
- 期间存在两条 sftp-server 进程(不同时间各起一条),疑似读/写走不同 SFTP 通道

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Locate the Rust remote SSH/SFTP client code and its handle lifecycle, using the `russh_sftp::client::rawsession` evidence and upstream remotefs-rs-ssh PR #22 as starting points. Reproduce the long-session failure with repeated Read/Write/Edit operations, then verify that the chosen fix prevents handle exhaustion or recovers the SFTP session.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
rust, tauri
Bereich
desktop, networking
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
42/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.