Repository navigation
Disassociate the wrapped handle when a throttled association stops - #8647
Merged
Aaronontheweb merged 2 commits intoSep 25, 2026
Merged
Aaronontheweb merged 2 commits into
Aaronontheweb merged 2 commits into
Conversation
…kkadotnet#8637) ThrottlerHandle.Disassociate only PoisonPilled its ThrottledAssociation actor, which never tore down the underlying TCP handle - sockets stayed open under the trttl adapter (applied by every MultiNodeSpec) until transport Shutdown force-closed them. ThrottledAssociation.PostStop now disassociates the wrapped handle exactly once, matching canonical Akka's postStop hook; the wrapped handle's Disassociate() is required to be idempotent, so this is safe even after an inbound disassociation.
Aaronontheweb
enabled auto-merge (squash)
September 25, 2026 13:00
Aaronontheweb
disabled auto-merge
September 25, 2026 13:01
Aaronontheweb
enabled auto-merge (squash)
September 25, 2026 13:01
…associate, rename a misleading test - ThrottledAssociation.PostStop: wrap the wrapped-handle Disassociate in try/finally so base.PostStop() (and OnTermination) always runs. - Remove the now-redundant explicit OriginalHandle.Disassociate() in the "InboundPayload before initialized" handler - PostStop already covers it. - Rename the inbound-disassociation test to describe what it actually checks (PostStop disassociates exactly once), and add a call-count assertion to the pre-existing "payload before handle" test so it would catch the removed redundant call coming back.
Aaronontheweb
added a commit
to Aaronontheweb/akka.net
that referenced
this pull request
Oct 2, 2026
…kkadotnet#8637) (akkadotnet#8647) ThrottlerHandle.Disassociate only PoisonPilled its ThrottledAssociation actor, which never tore down the underlying TCP handle - sockets stayed open under the trttl adapter (applied by every MultiNodeSpec) until transport Shutdown force-closed them. ThrottledAssociation.PostStop now disassociates the wrapped handle exactly once; the wrapped handle's Disassociate() is required to be idempotent, so this is safe even after an inbound disassociation. (cherry picked from commit 1dca4b4)
Aaronontheweb
added a commit
to Aaronontheweb/akka.net
that referenced
this pull request
Oct 3, 2026
…kkadotnet#8637) (akkadotnet#8647) ThrottlerHandle.Disassociate only PoisonPilled its ThrottledAssociation actor, which never tore down the underlying TCP handle - sockets stayed open under the trttl adapter (applied by every MultiNodeSpec) until transport Shutdown force-closed them. ThrottledAssociation.PostStop now disassociates the wrapped handle exactly once; the wrapped handle's Disassociate() is required to be idempotent, so this is safe even after an inbound disassociation. (cherry picked from commit 1dca4b4)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #8637
Problem
ThrottlerHandle.Disassociate()only sent aPoisonPillto itsThrottledAssociationactor. That actor never disassociated the wrappedAssociationHandle, so with thetrttladapter applied (everyMultiNodeSpecapplies[trttl, gremlin]), the underlying TCP socket stayed open on both peers until the transport'sShutdowneventually force-closed it, instead of a graceful close.Fix
ThrottledAssociationnow disassociates the wrapped handle fromPostStop(in a try/finally, sobase.PostStop()always runs), so it happens exactly once no matter why the actor stopped (explicit disassociate, Blackhole, a crash, or transport shutdown). This mirrors canonical Akka'sThrottledAssociation.postStop, which does the same unconditional call and relies on the wrapped handle'sDisassociate()being idempotent (a documented contract ofAssociationHandle.Disassociate) - so there's no double-disassociate risk if the peer already tore the connection down first. Two call sites that used to disassociate the wrapped handle directly, and would now double up withPostStop, were removed.Throttle mode behavior (Blackhole, TokenBucket) is otherwise unchanged - except that a new inbound association that gets blackholed during the handshake now closes its TCP socket as part of stopping, so the peer fails fast instead of waiting out the handshake timeout. This matches JVM Akka.
Testing
Added two tests to
ThrottlerManagerLifecycleSpec, using its existing stub transport/handle harness, and strengthened an existing one:ThrottlerHandle.Disassociate()now tears down the wrapped handleDisassociatednotification (peer closed first) still disassociates the wrapped handle exactly once, viaPostStopAll three fail on
dev(or would, in the strengthened case) and pass with this change. RanThrottlerTransportAdapterSpec+ the new/updated tests 5x, and the fullAkka.Remote.TestsTransportnamespace once - all green. Also ran a couple of MultiNode specs locally (AttemptSysMsgRedeliverySpec,RemoteNodeShutdownAndComesBackSpec) - both pass; no measurable termination-time change was observed locally, which is expected sinceDotNettyTransport.Shutdown(post-#8635) only waits on handles that already started a graceful close, so previously-unclosed throttled handles weren't being waited on either - this fix makes them close gracefully instead of via force-close, without changing the shutdown wait.Test-infrastructure only:
trttlisn't applied in default configs (applied-adapters = []).