Skip to content

Artery: give the single-lane outbound stream the same inner restart as the multi-lane path - #8479

Merged
Aaronontheweb merged 3 commits into
devfrom
fix/artery-single-lane-restart-parity
Aug 26, 2026
Merged

Artery: give the single-lane outbound stream the same inner restart as the multi-lane path#8479
Aaronontheweb merged 3 commits into
devfrom
fix/artery-single-lane-restart-parity

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Member

Closes #8477.

The multi-lane outbound path wraps its merged socket connection in RestartFlow.OnFailuresWithBackoff, so a transient TCP fault (connection refused on a fresh materialization, a port-rebind race, a reset mid-burst) reconnects without tearing down the stream and losing what the handshake/encode stages held in flight. The default single-lane path - the common case - wired the raw Tcp.OutgoingConnection directly: the same fault tripped the stream's kill switch and discarded the in-flight elements.

Fix: wrap the single-lane connection with the identical restart settings and max-inner-restarts bound the multi-lane path uses. The stream-id preamble moves inside the restart factory so every reconnect resends the connection header, matching the multi-lane wiring. The per-stream kill switch and WatchTermination keep their existing positions and semantics; the materialized-value chain is unchanged.

All 253 Artery unit tests pass; Akka.Remote builds clean under -warnaserror.

The lanes>1 outbound path already wraps its merged socket
connection in RestartFlow.OnFailuresWithBackoff so a transient
connect/write fault retries the socket alone, without tearing down
the lane chains and losing whatever they had in flight.

The default outbound-lanes=1 path (ordinary and large-message
streams materialized through MaterializeOutboundStream) had no
equivalent: a transient socket fault tripped the stream's kill
switch directly and discarded whatever the upstream handshake/encode
stages already had in flight, falling back to the slower outer
restart tier for every transient fault.

Wrap that connection the same way, with the same backoff settings
and the same max-inner-restarts constant used by the lanes path. The
stream-id preamble moves inside the restart factory so every
reconnect resends the connection header first, matching how the
lanes path already handles it. The per-stream kill switch and
WatchTermination keep their existing position and semantics.

Builds Akka.Remote clean with 0 warnings. All existing Artery unit
specs pass (253/253).
@Aaronontheweb Aaronontheweb added akka-remote artery Akka.Remote Artery Protocol akka.net v1.6 Akka.NET v1.6-related issues labels Aug 26, 2026

@Aaronontheweb Aaronontheweb left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

LGTM

@Aaronontheweb
Aaronontheweb enabled auto-merge (squash) August 26, 2026 02:27
@Aaronontheweb
Aaronontheweb merged commit e581901 into dev Aug 26, 2026
13 of 15 checks passed
@Aaronontheweb
Aaronontheweb deleted the fix/artery-single-lane-restart-parity branch August 26, 2026 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

akka.net v1.6 Akka.NET v1.6-related issues akka-remote artery Akka.Remote Artery Protocol

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Artery: single-lane outbound stream has no inner restart - transient socket faults lose in-flight messages

1 participant