Skip to content

feat(core): wire AsyncSshTransport into client remote transfer path (#1805)#4290

Merged
oferchen merged 1 commit into
masterfrom
feat/wire-async-ssh-transport-core-1805
May 17, 2026
Merged

feat(core): wire AsyncSshTransport into client remote transfer path (#1805)#4290
oferchen merged 1 commit into
masterfrom
feat/wire-async-ssh-transport-core-1805

Conversation

@oferchen
Copy link
Copy Markdown
Owner

Summary

  • New async-ssh feature on the core crate that pulls in rsync_io/async-ssh and dep:tokio, gating the tokio-backed SSH transport wiring.
  • New crates/core/src/client/remote/async_ssh_transport.rs module that spawns AsyncSshTransport, bridges its AsyncRead/AsyncWrite halves through the ChannelReader/ChannelWriter adapters from PR feat(rsync_io): ChannelReader/Writer AsyncRead/AsyncWrite adapters (#1797) #4271, and runs the existing sync handshake + server-framing layer under tokio::task::spawn_blocking via a pair of std::sync::mpsc channels.
  • Client driver opts in when OC_RSYNC_ASYNC_SSH=1 is set; CLI flag work is tracked separately as Handle forced missing cargo tools in packaging tests #1806.
  • Sync SshTransport path remains the default. Progress observation and remote-to-remote proxy transfers stay on the sync path on the async wiring for now.

Architecture

 spawn_blocking thread          tokio runtime (current_thread)
 SyncWriter ──┐                                         ┌── AsyncSshTransport
              │  std::sync::mpsc  ChannelReader (Async) │
              └─────────────────► (pump)  ─────────────►│  stdin (AsyncWrite)
 SyncReader ◄─┐                                         │  stdout (AsyncRead)
              │  std::sync::mpsc  ChannelWriter (Async) │
              └◄──────────────── (pump)  ◄──────────────│

Deferred to #1806

  • CLI surface for selecting the async transport (currently env-var only).
  • Async-side progress observer plumbing (sync path keeps --info=progress2 parity).
  • Async remote-to-remote proxy transfers.
  • Async stderr capture for child-process diagnostics.

Test plan

  • cargo fmt --all -- --check
  • cargo check -p core --features async-ssh --no-default-features
  • cargo check -p core (default features)
  • cargo check --workspace --all-features
  • cargo clippy -p core --features async-ssh --no-default-features --all-targets --no-deps
  • cargo clippy -p core --all-features --all-targets --no-deps
  • cargo nextest run -p core --features async-ssh --no-default-features -E 'test(async_ssh_transport)' (8/8 pass)
  • cargo nextest run -p core -E 'test(ssh_transfer)' (15/15 pass, no regression on sync path)

…1805)

Adds an async-ssh feature on the core crate that pulls in the tokio-backed
`rsync_io::ssh::AsyncSshTransport` (PR #4273) and bridges it into the
existing synchronous client transfer orchestration. A new
`async_ssh_transport` module spawns the async transport, copies bytes
between its `AsyncRead`/`AsyncWrite` halves and the sync handshake +
server-framing layer via the `ChannelReader`/`ChannelWriter` adapters,
and runs the sync server flow under `tokio::task::spawn_blocking`.

The client driver picks the async path when the `OC_RSYNC_ASYNC_SSH=1`
env var is set; the CLI flag is deferred to #1806. Progress observation
and remote-to-remote proxy transfers remain on the sync path for now.
@oferchen oferchen merged commit ab0b33f into master May 17, 2026
13 of 14 checks passed
oferchen added a commit that referenced this pull request May 17, 2026
…4295)

Adds the bridge primitives that let the existing synchronous multiplex
and transfer code drive an async russh channel without being ported to
async. Builds on PR #4290 (#1805) which wired the async SshTransport
into the client driver via the OC_RSYNC_ASYNC_SSH env var.

The new `ssh::embedded::sync_bridge` module is gated under
`embedded-ssh` and exposes:

- `SyncAsyncBridge<S>`: a generic facade that takes any
  `AsyncRead + AsyncWrite + Unpin + Send + 'static` stream (including
  russh's `ChannelStream`) and exposes `std::io::Read + std::io::Write`
  by driving an internal current-thread tokio runtime via `block_on`.
- `into_sync_halves(russh::Channel)` returning `(SyncReader, SyncWriter)`
  halves backed by a background pump task and bounded
  `std::sync::mpsc` / `tokio::sync::mpsc` queues - the inverse of the
  existing `ChannelReader`/`ChannelWriter` adapters in
  `channel_adapter.rs`.
- `into_sync_halves_with_capacity` for callers that need a different
  queue depth (used by the backpressure test).
@github-actions github-actions Bot added the enhancement New feature or request label May 17, 2026
oferchen added a commit that referenced this pull request May 18, 2026
…1805) (#4290)

Adds an async-ssh feature on the core crate that pulls in the tokio-backed
`rsync_io::ssh::AsyncSshTransport` (PR #4273) and bridges it into the
existing synchronous client transfer orchestration. A new
`async_ssh_transport` module spawns the async transport, copies bytes
between its `AsyncRead`/`AsyncWrite` halves and the sync handshake +
server-framing layer via the `ChannelReader`/`ChannelWriter` adapters,
and runs the sync server flow under `tokio::task::spawn_blocking`.

The client driver picks the async path when the `OC_RSYNC_ASYNC_SSH=1`
env var is set; the CLI flag is deferred to #1806. Progress observation
and remote-to-remote proxy transfers remain on the sync path for now.
oferchen added a commit that referenced this pull request May 18, 2026
…4295)

Adds the bridge primitives that let the existing synchronous multiplex
and transfer code drive an async russh channel without being ported to
async. Builds on PR #4290 (#1805) which wired the async SshTransport
into the client driver via the OC_RSYNC_ASYNC_SSH env var.

The new `ssh::embedded::sync_bridge` module is gated under
`embedded-ssh` and exposes:

- `SyncAsyncBridge<S>`: a generic facade that takes any
  `AsyncRead + AsyncWrite + Unpin + Send + 'static` stream (including
  russh's `ChannelStream`) and exposes `std::io::Read + std::io::Write`
  by driving an internal current-thread tokio runtime via `block_on`.
- `into_sync_halves(russh::Channel)` returning `(SyncReader, SyncWriter)`
  halves backed by a background pump task and bounded
  `std::sync::mpsc` / `tokio::sync::mpsc` queues - the inverse of the
  existing `ChannelReader`/`ChannelWriter` adapters in
  `channel_adapter.rs`.
- `into_sync_halves_with_capacity` for callers that need a different
  queue depth (used by the backpressure test).
oferchen added a commit that referenced this pull request May 18, 2026
…1805) (#4290)

Adds an async-ssh feature on the core crate that pulls in the tokio-backed
`rsync_io::ssh::AsyncSshTransport` (PR #4273) and bridges it into the
existing synchronous client transfer orchestration. A new
`async_ssh_transport` module spawns the async transport, copies bytes
between its `AsyncRead`/`AsyncWrite` halves and the sync handshake +
server-framing layer via the `ChannelReader`/`ChannelWriter` adapters,
and runs the sync server flow under `tokio::task::spawn_blocking`.

The client driver picks the async path when the `OC_RSYNC_ASYNC_SSH=1`
env var is set; the CLI flag is deferred to #1806. Progress observation
and remote-to-remote proxy transfers remain on the sync path for now.
oferchen added a commit that referenced this pull request May 18, 2026
…4295)

Adds the bridge primitives that let the existing synchronous multiplex
and transfer code drive an async russh channel without being ported to
async. Builds on PR #4290 (#1805) which wired the async SshTransport
into the client driver via the OC_RSYNC_ASYNC_SSH env var.

The new `ssh::embedded::sync_bridge` module is gated under
`embedded-ssh` and exposes:

- `SyncAsyncBridge<S>`: a generic facade that takes any
  `AsyncRead + AsyncWrite + Unpin + Send + 'static` stream (including
  russh's `ChannelStream`) and exposes `std::io::Read + std::io::Write`
  by driving an internal current-thread tokio runtime via `block_on`.
- `into_sync_halves(russh::Channel)` returning `(SyncReader, SyncWriter)`
  halves backed by a background pump task and bounded
  `std::sync::mpsc` / `tokio::sync::mpsc` queues - the inverse of the
  existing `ChannelReader`/`ChannelWriter` adapters in
  `channel_adapter.rs`.
- `into_sync_halves_with_capacity` for callers that need a different
  queue depth (used by the backpressure test).
@oferchen oferchen deleted the feat/wire-async-ssh-transport-core-1805 branch May 19, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant