Skip to content

SFTP download fix && Format#1172

Merged
GT-610 merged 6 commits into
mainfrom
sftp-download-perf
May 16, 2026
Merged

SFTP download fix && Format#1172
GT-610 merged 6 commits into
mainfrom
sftp-download-perf

Conversation

@GT-610
Copy link
Copy Markdown
Collaborator

@GT-610 GT-610 commented May 16, 2026

Summary by CodeRabbit

  • Bug Fixes

    • More reliable server status fetching with persistent-shell fallback and timeout handling.
    • Improved SFTP downloads: segmented transfers with stricter per-read timeouts and finer progress updates.
  • Improvements

    • Added “copy error” action in error dialogs for easier troubleshooting.
  • Code Quality

    • Large-scale formatting and readability updates across the codebase.
  • Tests

    • Added/extended tests for server import name-conflict resolution.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ffcc64b0-0332-4b7e-ac82-c9b308d137a5

📥 Commits

Reviewing files that changed from the base of the PR and between 138747b and 44a28d3.

📒 Files selected for processing (2)
  • lib/data/model/server/disk_smart.dart
  • lib/data/provider/container.dart
✅ Files skipped from review due to trivial changes (2)
  • lib/data/model/server/disk_smart.dart
  • lib/data/provider/container.dart

📝 Walkthrough

Walkthrough

This PR contains: (1) an SFTP download implementation switching from downloadTo to a segmented ranged-read loop with smaller read chunk size, single pending request, per-read timeouts, and progress updates; (2) ServerNotifier changes introducing _usePersistentShellForStatus, updateClient reset, and _runStatusCommand/_runStatusCommandWithExec with timeout fallback to exec; (3) a repository-wide set of formatting/line-wrapping refactors across many Dart files and tests; and (4) bump of the packages/dartssh2 submodule pointer.

Possibly related PRs

Suggested reviewers

  • lollipopkit
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sftp-download-perf

@coderabbitai coderabbitai Bot requested a review from lollipopkit May 16, 2026 06:28
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/data/model/sftp/worker.dart (1)

184-184: ⚡ Quick win

Use request-configured timeout instead of a hardcoded 30s read timeout.

Line 184 hardcodes read timeout and ignores req.timeoutSeconds, making transfer behavior inconsistent with prepare-time timeout handling. Consider deriving it from request config for predictable tuning.

🤖 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 `@lib/data/model/sftp/worker.dart` at line 184, The hardcoded Duration(seconds:
30) used in the .timeout call should be replaced with the request-configured
timeout value so transfer respects req.timeoutSeconds; update the .timeout(...)
invocation to derive the duration from req.timeoutSeconds (e.g.,
Duration(seconds: req.timeoutSeconds ?? <sensible_default>)) and ensure you
handle null/zero values and enforce a reasonable minimum to avoid indefinite or
too-short timeouts — change the .timeout call that currently uses
Duration(seconds: 30) to use req.timeoutSeconds and add validation fallback
logic.
🤖 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 `@lib/data/model/sftp/worker.dart`:
- Around line 171-202: The loop advances offset by the requested variable length
instead of the actual bytes received, which can skip data; update the logic in
the while loop that reads from openedRemoteFile.read(...) so that after each
segment you compute the actual bytesRead for that segment by summing
chunk.length values consumed (use the existing chunk loop/totalBytes tracking or
a local segmentBytes variable), then set offset += bytesRead; if bytesRead == 0
(no data returned for a requested segment) throw a SftpError('Download returned
0 bytes at offset=$offset') to fail fast and avoid silent corruption; ensure you
still keep totalBytes and chunkCount updated from chunk.length.

In `@lib/data/provider/server/single.dart`:
- Around line 564-575: _runStatusCommandWithExec currently awaits
client.run(statusCmd) with no timeout, which can hang; wrap the exec call in a
timeout (e.g. await client.run(statusCmd).timeout(Duration(seconds: X)) or use
the SSHClient run method's timeout parameter if available) and handle
TimeoutException by returning a suitable SSHDecoder.decode input or a
short-circuit error string so status refresh won't block; keep the rest of the
function intact (references: _runStatusCommandWithExec, client.run, statusCmd,
isWindows, SSHDecoder.decode, spi.name).

---

Nitpick comments:
In `@lib/data/model/sftp/worker.dart`:
- Line 184: The hardcoded Duration(seconds: 30) used in the .timeout call should
be replaced with the request-configured timeout value so transfer respects
req.timeoutSeconds; update the .timeout(...) invocation to derive the duration
from req.timeoutSeconds (e.g., Duration(seconds: req.timeoutSeconds ??
<sensible_default>)) and ensure you handle null/zero values and enforce a
reasonable minimum to avoid indefinite or too-short timeouts — change the
.timeout call that currently uses Duration(seconds: 30) to use
req.timeoutSeconds and add validation fallback logic.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2b85dd92-2c34-4ea9-af42-d81de77be296

📥 Commits

Reviewing files that changed from the base of the PR and between f8baa19 and c2c6c57.

📒 Files selected for processing (101)
  • lib/app.dart
  • lib/core/chan.dart
  • lib/core/extension/server.dart
  • lib/core/extension/ssh_client.dart
  • lib/core/service/ssh_discovery.dart
  • lib/core/utils/comparator.dart
  • lib/core/utils/host_key_helper.dart
  • lib/core/utils/server_dedup.dart
  • lib/core/utils/ssh_auth.dart
  • lib/core/utils/ssh_config.dart
  • lib/data/helper/ssh_decoder.dart
  • lib/data/helper/system_detector.dart
  • lib/data/model/ai/ask_ai_models.dart
  • lib/data/model/app/bak/backup.dart
  • lib/data/model/app/bak/backup2.dart
  • lib/data/model/app/bak/backup_service.dart
  • lib/data/model/app/net_view.dart
  • lib/data/model/app/scripts/cmd_types.dart
  • lib/data/model/app/scripts/script_builders.dart
  • lib/data/model/app/scripts/script_consts.dart
  • lib/data/model/app/scripts/shell_func.dart
  • lib/data/model/container/image.dart
  • lib/data/model/container/ps.dart
  • lib/data/model/server/amd.dart
  • lib/data/model/server/battery.dart
  • lib/data/model/server/conn.dart
  • lib/data/model/server/connection_stat.dart
  • lib/data/model/server/custom.dart
  • lib/data/model/server/discovery_result.dart
  • lib/data/model/server/disk_smart.dart
  • lib/data/model/server/memory.dart
  • lib/data/model/server/net_speed.dart
  • lib/data/model/server/nvdia.dart
  • lib/data/model/server/ping_result.dart
  • lib/data/model/server/port_forward.dart
  • lib/data/model/server/private_key_info.dart
  • lib/data/model/server/pve.dart
  • lib/data/model/server/sensors.dart
  • lib/data/model/server/server_status_update_req.dart
  • lib/data/model/server/system.dart
  • lib/data/model/server/time_seq.dart
  • lib/data/model/server/windows_parser.dart
  • lib/data/model/server/wol_cfg.dart
  • lib/data/model/sftp/worker.dart
  • lib/data/model/ssh/virtual_key.dart
  • lib/data/provider/container.dart
  • lib/data/provider/private_key.dart
  • lib/data/provider/server/single.dart
  • lib/data/provider/sftp.dart
  • lib/data/provider/snippet.dart
  • lib/data/provider/systemd.dart
  • lib/data/res/github_id.dart
  • lib/data/res/store.dart
  • lib/data/ssh/session_manager.dart
  • lib/data/store/container.dart
  • lib/data/store/history.dart
  • lib/data/store/port_forward.dart
  • lib/data/store/private_key.dart
  • lib/data/store/setting.dart
  • lib/data/store/snippet.dart
  • lib/intro.dart
  • lib/main.dart
  • lib/view/page/home.dart
  • lib/view/page/iperf.dart
  • lib/view/page/port_forward.dart
  • lib/view/page/private_key/edit.dart
  • lib/view/page/private_key/list.dart
  • lib/view/page/server/discovery/discovery.dart
  • lib/view/page/server/discovery/widget.dart
  • lib/view/page/server/tab/card_stat.dart
  • lib/view/page/server/tab/content.dart
  • lib/view/page/server/tab/landscape.dart
  • lib/view/page/server/tab/tab.dart
  • lib/view/page/server/tab/top_bar.dart
  • lib/view/page/server/tab/utils.dart
  • lib/view/page/setting/entries/ssh.dart
  • lib/view/page/setting/platform/platform_pub.dart
  • lib/view/page/setting/seq/srv_func_seq.dart
  • lib/view/page/snippet/edit.dart
  • lib/view/page/ssh/page/init.dart
  • lib/view/page/ssh/page/virt_key.dart
  • lib/view/page/ssh/tab.dart
  • lib/view/page/storage/sftp_mission.dart
  • lib/view/page/systemd.dart
  • lib/view/widget/omit_start_text.dart
  • make.dart
  • packages/dartssh2
  • test/amd_smi_test.dart
  • test/container_test.dart
  • test/core_utils_test.dart
  • test/disabled_cmd_types_test.dart
  • test/net_speed_test.dart
  • test/script_builder_test.dart
  • test/server_dedup_test.dart
  • test/server_edit_logic_test.dart
  • test/server_status_update_req_test.dart
  • test/ssh_config_test.dart
  • test/system_dist_test.dart
  • test/terminal_output_buffer_test.dart
  • test/uptime_test.dart
  • test/windows_test.dart
💤 Files with no reviewable changes (1)
  • lib/view/page/ssh/tab.dart

Comment thread lib/data/model/sftp/worker.dart
Comment thread lib/data/provider/server/single.dart
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 16, 2026
@GT-610 GT-610 merged commit 2df593c into main May 16, 2026
3 checks passed
@GT-610 GT-610 deleted the sftp-download-perf branch May 16, 2026 06:53
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.

1 participant