Skip to content

Artery: port InboundQuarantineCheck - #8416

Merged
Aaronontheweb merged 9 commits into
devfrom
fix/artery-inbound-quarantine-check
Aug 26, 2026
Merged

Artery: port InboundQuarantineCheck#8416
Aaronontheweb merged 9 commits into
devfrom
fix/artery-inbound-quarantine-check

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Member

Artery enforced quarantine on the outbound path only, with the deliberate Pekko-parity carve-out that lets ActorSelection messages pierce to reach a new incarnation. But the pierce's reply was then delivered on the quarantiner's inbound side — there was no stage dropping traffic from a quarantined uid and no reactive re-notification to the quarantined peer, so ExpectNoMsg-after-quarantine assertions fail and a quarantined system is told only once. Found via the Artery MNTR lanes on #8373 (RemoteQuarantinePiercingSpec, PiercingShouldKeepQuarantineSpec, RemoteRestartedQuarantinedSpec).

This ports Pekko's InboundQuarantineCheck into both inbound sinks: envelopes from a quarantined uid are dropped, and each drop (except quarantine notices and heartbeats) reactively sends the origin a Quarantined control message. RemoteRestartedQuarantinedSpec's assertion is aligned with Pekko's artery variant of the same spec; classic behavior is unchanged.

Getting the three specs green over artery surfaced two more gaps, fixed here too. An ordinary/large outbound stream that terminated while its association was quarantined left the materialize-once gate latched with no stream behind it, so a quarantine-piercing ActorSelection send (or any send after a new incarnation lifted the quarantine) could never re-dial the restarted peer; the gate is now released in that case while the timer-driven reconnect stays suppressed. And both restart specs' fresh systems only pinned the classic dot-netty port, so under artery the restarted node came back on a random port the quarantiner could never reach — the artery canonical host/port is now pinned too, and RemoteRestartedQuarantinedSpec gains the before-quarantined barrier from Pekko's artery variant.

Quarantine was enforced on the outbound path only - envelopes arriving from a quarantined uid were delivered instead of dropped, and the quarantined peer was only notified once, proactively. Port Pekko's inbound stage: drop inbound traffic from quarantined uids in both inbound sinks and reactively re-notify the origin per dropped message. Align RemoteRestartedQuarantinedSpec's assertion with Pekko's artery variant.

Greening the quarantine specs over artery surfaced two more gaps, fixed here. An ordinary/large outbound stream that died while quarantined left its materialize-once gate latched, so a quarantine-piercing ActorSelection send could never re-dial a restarted peer - the gate is now released (timer-driven reconnect stays suppressed) so send-driven re-materialization works. And the restart specs' fresh systems pinned only the classic dot-netty port, so under artery the restarted node came back on a random port; both transports' ports are now pinned and the before-quarantined barrier from Pekko's artery variant is added.
With inbound-lanes > 1, ordinary traffic fans out inside the processing stage and bypasses the sink where InboundQuarantineCheckStage sits - the lane path had known-origin and blackhole gates but no quarantine gate. Inline the same drop-and-renotify logic after the known-origin check, share the skip set with the stage, and lock it with a laned quarantine spec.
@Aaronontheweb Aaronontheweb added artery Akka.Remote Artery Protocol akka-remote akka.net v1.6 Akka.NET v1.6-related issues labels Jul 30, 2026
The comments added by this PR were dense enough to slow down review. One class
summary ran a single 90-word sentence through four nested parentheticals before
it resolved. Emphasis was in capitals often enough to stop carrying meaning, and
cross-references cited line numbers in another codebase that will drift and
cannot be checked from here.

Rewrites all of them to ASD-STE100 conventions: one idea per sentence, short
sentences, active voice, plain words, consistent terms. Procedures become
numbered or bulleted lists. Pipeline position and rationale move out of the
opening sentence into their own paragraphs, so a reader can find either one
without parsing the whole block.

Keeps the cross-references, which are the convention in this code, but reduces
each to a single line without line numbers.

No executable code changes - the diff is comments only.
The spec said only THAT ActorSelectionMessage pierces a quarantined
association, never what the pierce may reach. It now states the resolved
semantics: the pierce is not uid-checked, may reach the quarantined incarnation
itself, and only the reply is dropped - the sender cannot discover a restarted
peer without sending to it. Four scenarios cover the outbound exemption, the
inbound drop-and-renotify, the new-incarnation lift, and the no-retaliation
rule, so the behavior is regression-testable instead of folklore.

Also records in design.md that remove-quarantined-association-after is
specified but not yet implemented (filed separately), and tightens the wording
of the comments this PR adds.
@Aaronontheweb
Aaronontheweb force-pushed the fix/artery-inbound-quarantine-check branch from 02787d3 to f0bbe14 Compare August 25, 2026 20:51
@Aaronontheweb
Aaronontheweb merged commit c1c58f0 into dev Aug 26, 2026
12 of 15 checks passed
@Aaronontheweb
Aaronontheweb deleted the fix/artery-inbound-quarantine-check branch August 26, 2026 02:05
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 multi node spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant