Commit c486c79
committed
Artery: stop dropping the first ordinary message when the peer dialed first
Fixes #8496.
`OutboundHandshakeStage.PreStart` treated "this association already has a
`UniqueRemoteAddress`" as "our handshake is done" and skipped straight to
`Completed`. That field is also set by the INBOUND direction - when WE handle
the peer's `HandshakeReq` - so it proves we know the peer's uid, not that the
peer knows ours. When a peer dialed us first, our first outbound ordinary
stream therefore sent no `HandshakeReq` of its own, and our first user message
raced our `HandshakeRsp` (a different TCP connection, no ordering relationship)
into the peer's unknown-origin gate:
Dropping inbound message [Akka.Actor.ActorSelectionMessage] from unknown
origin uid [817823530] (no completed handshake for this uid yet).
Ordinary messages have no resend path, so the message was gone. The receiving
side documented an invariant ("the sender's gate cannot complete before we have
processed its Req") that the `PreStart` shortcut quietly broke.
`AssociationState.OutboundHandshakeCompleted` now records, per INCARNATION,
whether the peer has answered a `HandshakeReq` of ours. Only the new
`CompleteOutboundHandshake` sets it, and only `InboundHandshakeStage.HandleRsp`
calls that - a Rsp is the sole event proving the peer registered our uid. The
flag rides the same immutable snapshot and CAS swap as the rest of the
association state: a uid change resets it, `Quarantine` clears it, so it never
outlives the incarnation it describes.
Two gates consult it, both for ordinary/large/lane streams only:
* `PreStart`'s fast path (`CanSkipOwnHandshake`) - so a stream materialized
against an inbound-only association runs the normal, well-tested handshake
path instead of shortcutting.
* `RefreshCompletionFromContext` - load-bearing too, since the generation
counter it already checked is advanced by the peer's own inbound Req: without
it, a stream that did send its Req would complete on the peer's Req *retry*
landing while we wait for our Rsp, which is the same bug through the back
door.
The CONTROL stream deliberately keeps the old, weaker rule. Its traffic is never
subject to the receiver's unknown-origin drop - every control envelope
(handshake, heartbeat, quarantine notice, system messages and their Ack/Nack) is
dispatched regardless of whether the origin uid is registered - and it must be
able to complete on an inbound handshake: the `HandshakeRsp` we owe a peer is
enqueued on that very control queue, so a strict rule there would deadlock two
systems that dial each other at the same instant, each holding the Rsp the other
is waiting for.
`ForceReqOnStart` is unaffected: it still forces the full handshake path, and the
two conditions compose - the fast path is skipped when either says so.
Also, at both inbound gates (`InboundHandshakeStage` and the lane-routed copy in
`ArteryInboundProcessingStage`), the unknown-origin drop is raised from DEBUG to
a rate-limited WARNING: the first drop warns at once, later ones at most once
per 10s carrying the count suppressed in between. This class of loss should be
diagnosable in the field, not invisible.
Tests. `ArteryPeerDialedFirstSpec` covers the issue's stage-level repro (an
association created by a real inbound `HandshakeReq`; the ordinary stage must
send its own Req and hold traffic until a real `HandshakeRsp` arrives), the
peer's-Req-retry variant, fast-path preservation, the new warning, and an
end-to-end test over two real Artery systems where B dials A first and A's
`HandshakeRsp` is dropped - the deterministic form of the race. Four of the five
fail on unfixed code; the fast-path test passes before and after, as it must.
`AssociationStateSpec` gains the transition, incarnation-reset and quarantine
coverage for the new flag. The invariant comment on `InboundHandshakeStage` now
describes the corrected construction.1 parent e6e014d commit c486c79
9 files changed
Lines changed: 614 additions & 35 deletions
File tree
- src/core
- Akka.Remote.Tests/Artery
- Akka.Remote/Artery
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| |||
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
155 | | - | |
| 155 | + | |
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| |||
268 | 268 | | |
269 | 269 | | |
270 | 270 | | |
271 | | - | |
| 271 | + | |
272 | 272 | | |
273 | 273 | | |
274 | 274 | | |
| |||
285 | 285 | | |
286 | 286 | | |
287 | 287 | | |
288 | | - | |
| 288 | + | |
289 | 289 | | |
290 | 290 | | |
291 | 291 | | |
| |||
Lines changed: 327 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 59 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
97 | 156 | | |
98 | 157 | | |
99 | 158 | | |
| |||
Lines changed: 25 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
331 | 338 | | |
332 | 339 | | |
| 340 | + | |
| 341 | + | |
333 | 342 | | |
334 | 343 | | |
335 | 344 | | |
| |||
762 | 771 | | |
763 | 772 | | |
764 | 773 | | |
765 | | - | |
766 | | - | |
767 | | - | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
768 | 790 | | |
769 | 791 | | |
770 | 792 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
996 | 996 | | |
997 | 997 | | |
998 | 998 | | |
999 | | - | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
1000 | 1013 | | |
1001 | 1014 | | |
1002 | 1015 | | |
1003 | 1016 | | |
1004 | 1017 | | |
1005 | 1018 | | |
1006 | | - | |
| 1019 | + | |
1007 | 1020 | | |
1008 | 1021 | | |
1009 | 1022 | | |
| |||
1137 | 1150 | | |
1138 | 1151 | | |
1139 | 1152 | | |
1140 | | - | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
1141 | 1174 | | |
1142 | 1175 | | |
1143 | 1176 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
41 | 45 | | |
42 | 46 | | |
43 | 47 | | |
| 48 | + | |
44 | 49 | | |
45 | 50 | | |
46 | 51 | | |
47 | 52 | | |
48 | 53 | | |
49 | | - | |
| 54 | + | |
50 | 55 | | |
51 | | - | |
| 56 | + | |
| 57 | + | |
52 | 58 | | |
53 | 59 | | |
54 | 60 | | |
| |||
63 | 69 | | |
64 | 70 | | |
65 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
66 | 82 | | |
67 | 83 | | |
68 | 84 | | |
| |||
80 | 96 | | |
81 | 97 | | |
82 | 98 | | |
83 | | - | |
| 99 | + | |
84 | 100 | | |
85 | 101 | | |
86 | 102 | | |
87 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
88 | 115 | | |
89 | 116 | | |
90 | 117 | | |
91 | 118 | | |
92 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
93 | 125 | | |
94 | | - | |
| 126 | + | |
95 | 127 | | |
96 | 128 | | |
97 | | - | |
| 129 | + | |
98 | 130 | | |
99 | 131 | | |
100 | 132 | | |
| |||
113 | 145 | | |
114 | 146 | | |
115 | 147 | | |
116 | | - | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
117 | 151 | | |
118 | 152 | | |
119 | 153 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
50 | 59 | | |
51 | 60 | | |
52 | 61 | | |
| |||
129 | 138 | | |
130 | 139 | | |
131 | 140 | | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
132 | 144 | | |
133 | 145 | | |
134 | 146 | | |
| |||
0 commit comments