Skip to content

refactor(iroh)!: redesign path observation API#4188

Open
Frando wants to merge 1 commit intoFrando/noq-path-stats-on-closefrom
Frando/path-refactor-new
Open

refactor(iroh)!: redesign path observation API#4188
Frando wants to merge 1 commit intoFrando/noq-path-stats-on-closefrom
Frando/path-refactor-new

Conversation

@Frando
Copy link
Copy Markdown
Member

@Frando Frando commented Apr 27, 2026

Depends on n0-computer/noq#617
Based on #4229

This replaces the current PathWatcher with a new combination of primitives.

  • Connection::paths returns PathList<'conn>, a list of the currently-open paths. Iteration yields Path<'conn> with access to the remote address, selection state, and path stats. The PathList is a snapshot in time (ie., once returned from Connection::paths won't change for changes in the path list). It is also lifetime-bound to the Connection (which gives us unconditional access to path stats right out of the noq state).
  • Connection::path_events() returns a PathEventStream of path events. This stream is lifetime-free, can be sent to other tasks, and does not keep the Connection alive. The subscription is registered immediately at call time so pairing it with a subsequent paths() read produces a race-free check-then-wait loop.
  • Connection::path_updates returns a stream that yields PathList<'conn> whenever the path list changes (ie. on path open/close or selection change)

PathEvent has four variants: Opened, Closed (with last_stats inline), Selected, and a Lagged (with the missed count) to account for the (rare) case of a broadcast stream lag.

Closed paths are no longer retained in Paths. Consumers that need totals over the connection's lifetime accumulate from PathEvent:: Closed; the transfer.rs example's spawn_stats_collector demonstrates this pattern.

Internally, the path store splits into two handles sharing an Mutex<State>, containing a SmallVec of (PathId, TransportAddr) plus the selected path id. PathStateSender, owned by the RemoteStateActor, is the sole mutator and holds the broadcast Sender. PathStateReceiver, held by the Connection, reads via ArcSwap and subscribes via a WeakSender. When the ConnectionState is dropped, the broadcast Sender is dropped with it and outstanding event streams end naturally; new subscriptions on a closed connection where the remote state actor already dropped its state then yield an already-closed stream.

Final per-path statistics now come from noq::Closed::path_stats at connection close time, via n0-computer/noq#617.

Breaking Changes

  • removed: iroh::endpoint::PathWatcher, iroh::endpoint::PathInfo, iroh::endpoint::PathInfoList, iroh::endpoint::PathInfoListIter.
  • changed: Connection::paths returns PathList<'_> instead of PathWatcher. Path<'_> replaces PathInfo; Path::stats is now infallible
  • changed: ConnectionInfo::paths is removed in favour of ConnectionInfo::path_events. ConnectionInfo::selected_path now returns Option<TransportAddr> instead of Option<PathInfo>.
  • added: iroh::endpoint::Path, iroh::endpoint::Paths, iroh::endpoint::PathEvent (with Opened, Closed, Selected, Lagged variants), iroh::endpoint::PathEventStream, Connection::path_events, ConnectionInfo::path_events.

Change checklist

  • Self-review.
  • Documentation updates following the style guide.
  • Tests updated.
  • All breaking changes documented.

@Frando Frando force-pushed the Frando/path-refactor-new branch from aee38bd to f418de8 Compare April 27, 2026 12:58
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/4188/docs/iroh/

Last updated: 2026-05-05T13:40:21Z

@n0bot n0bot Bot added this to iroh Apr 27, 2026
@github-project-automation github-project-automation Bot moved this to 🚑 Needs Triage in iroh Apr 27, 2026
@Frando Frando force-pushed the Frando/path-refactor-new branch from f418de8 to 15f83e3 Compare April 27, 2026 14:13
@Frando Frando changed the base branch from main to Frando/weak-connection-handle April 27, 2026 14:13
@Frando Frando force-pushed the Frando/weak-connection-handle branch from 8d3ec38 to ea4c208 Compare April 27, 2026 14:14
@Frando Frando force-pushed the Frando/path-refactor-new branch from 15f83e3 to a5d7b28 Compare April 27, 2026 14:14
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

Netsim report & logs for this PR have been generated and is available at: LOGS
This report will remain available for 3 days.

Last updated for commit: 0c083d0

@Frando Frando force-pushed the Frando/path-refactor-new branch 2 times, most recently from 8c8a892 to e99bc03 Compare April 27, 2026 21:23
@Frando Frando force-pushed the Frando/weak-connection-handle branch from ea4c208 to 3c9c395 Compare April 29, 2026 09:25
@Frando Frando force-pushed the Frando/path-refactor-new branch from e99bc03 to 4be4d88 Compare April 29, 2026 12:24
@Frando Frando changed the base branch from Frando/weak-connection-handle to main April 29, 2026 12:24
@Frando Frando force-pushed the Frando/path-refactor-new branch 4 times, most recently from 148e40d to 72a8078 Compare May 4, 2026 12:28
@Frando Frando force-pushed the Frando/path-refactor-new branch from 1d5d67c to 488a321 Compare May 5, 2026 10:54
@Frando Frando changed the base branch from main to Frando/noq-path-stats-on-close May 5, 2026 10:54
@Frando Frando force-pushed the Frando/path-refactor-new branch from 488a321 to a5b561b Compare May 5, 2026 11:13
@Frando Frando marked this pull request as ready for review May 5, 2026 11:14
@Frando Frando force-pushed the Frando/path-refactor-new branch 2 times, most recently from d0dc079 to d2b7403 Compare May 5, 2026 13:06
@dignifiedquire dignifiedquire added this to the v1.0.0-rc.0 milestone May 5, 2026
@Frando Frando force-pushed the Frando/noq-path-stats-on-close branch from 524f70d to 8e10c37 Compare May 5, 2026 13:17
@Frando Frando force-pushed the Frando/path-refactor-new branch 2 times, most recently from f07effc to 19b034e Compare May 5, 2026 13:26
@Frando Frando force-pushed the Frando/path-refactor-new branch from 19b034e to dd59f9f Compare May 5, 2026 13:37
},
/// The subscriber fell behind and missed events.
///
/// The current state is recoverable via [`Connection::paths`].
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what exactly does this mean?

Frando added a commit that referenced this pull request May 5, 2026
…ed (#4229)

## Description

Updates `noq` and adapts iroh to the changes in
n0-computer/noq#617 by reexporting
`noq::Closed`.

## Breaking Changes

* changed: The `OnClosed` future returned from
`iroh::endpoint::WeakConnectionHandle::closed` now resolves to
`iroh::endpoint::Closed`, a struct with public fields for the close
reason, connection stats, and path stats.

## Notes & open questions

It would be nice to have the `TransportAddr` available for the path
stats, but we don't have that info available for paths that were already
closed earlier. Use the new APIs in #4188 instead if this needed.

## Change checklist
<!-- Remove any that are not relevant. -->
- [x] Self-review.
- [x] Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.
- [x] Tests if relevant.
- [x] All breaking changes documented.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🚑 Needs Triage

Development

Successfully merging this pull request may close these issues.

2 participants