Skip to content

dev/tunnel: surface liveness so callers can detect a dead background task #29

Description

@I-am-nothing

Goal

`TunnelHandle::shutdown()` is currently fire-and-forget — if the background task exits because the WSS died, the host process has no way to learn. Inbound calls silently stop arriving and the developer is confused why their tunnel "works" but routing doesn't.

Surface liveness so the host can react (reconnect, surface error, exit).

Sketch

Two reasonable shapes:

  1. JoinHandle exposed: the host `await`s it (or polls) to know the task ended.
    ```rust
    pub(super) struct TunnelHandle {
    pub session_id: String,
    shutdown: Arc,
    task: tokio::task::JoinHandle,
    }
    ```
  2. Watch channel: `tokio::sync::watch` lets multiple callers observe state transitions (Connected, Disconnecting, Disconnected, Error).

(2) composes better with future health-UI (`mirrorstack dev status`) and surface-area-wise stays in dev/tunnel.rs. (1) is simpler.

Why this matters in practice

Without it, the silent-death paths the simplify reviewer flagged are actionable internally (we eprintln warnings) but the dev::run loop spawning the tunnel can't tell the tunnel died. A dev does `mirrorstack dev --tunnel`, the tunnel drops at minute 14 due to network blip, and 16 minutes of inbound calls silently 404 from dispatch's perspective.

Acceptance

  • After tunnel-task exit (any reason), the host can detect within ~1s
  • `shutdown()` followed by an immediate liveness-check returns Disconnecting/Disconnected
  • Test: simulate stream close server-side, verify host observes the drop

Deps

Estimate

~80 LoC + tests. Probably ~45 min.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions