Commit fc83f91
committed
test: fix TcpProxy close/race in test_client_routes.py NLB test helper
TcpProxy.stop()/drop_connections() used to close a connection's sockets
directly, from the manager thread, while that connection's own forwarder
thread could still be blocked in select()/recv() on those exact file
descriptors -- a classic close-under-concurrent-user race. Since fds are
process-global, closing them could let the OS silently recycle the fd
number into a brand new connection before the stale forwarder thread's
blocked call unwound, causing it to read/write/close a socket that no
longer belonged to it (observed here as unhandled
"ValueError: file descriptor cannot be a negative integer (-1)" crashes
in _forward_loop once a socket was closed out from under it). stop()
also only ever joined the accept-loop thread, never the per-connection
forwarder threads it had just closed sockets out from under.
Fix, scoped entirely to this test helper (no driver code touched):
- TcpProxy._connections now maps (client_sock, target_sock) -> the
forwarder thread serving that pair.
- stop()/drop_connections() now shut down (SHUT_RDWR) both sockets --
safe to do concurrently with a blocked select()/recv(), unlike
close() -- and then join() every forwarder thread before returning.
Only the forwarder thread itself ever closes its own sockets now,
and only after it has fully stopped using them.
- _handle_new_connection starts the forwarder thread before publishing
it into _connections, so a concurrent stop()/drop_connections() can
never observe (and try to join) a thread that hasn't started yet.
- NLBEmulator.add_node()/remove_node() now serialize against each
other via an RLock, so a new proxy/connection can never be created
while another thread's remove_node() is still tearing one down.
Fixes #948.
Validation:
- Standalone stress harness (no CCM needed) driving concurrent
clients through TcpProxy while repeatedly calling
drop_connections()/stop()+restart from another thread: pre-fix,
40 iterations produced 162 unhandled ValueError crashes; post-fix,
40 iterations (same parameters) and a follow-up 150-iteration run
produced zero corruptions/exceptions/leaked threads.
- Full end-to-end runs of
TestFullNodeReplacementThroughNlb::test_should_survive_full_node_replacement_through_nlb
against a real CCM cluster, both before and after the fix, to
check for behavioral regressions and reproduce the reported
flakiness.1 parent 9b5b037 commit fc83f91
1 file changed
Lines changed: 71 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
95 | | - | |
96 | 95 | | |
97 | 96 | | |
98 | 97 | | |
99 | 98 | | |
100 | 99 | | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
| 100 | + | |
105 | 101 | | |
106 | 102 | | |
107 | 103 | | |
| |||
120 | 116 | | |
121 | 117 | | |
122 | 118 | | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
| 119 | + | |
127 | 120 | | |
128 | 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 | + | |
129 | 149 | | |
130 | 150 | | |
131 | 151 | | |
| |||
153 | 173 | | |
154 | 174 | | |
155 | 175 | | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | 176 | | |
161 | 177 | | |
162 | 178 | | |
163 | | - | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
164 | 202 | | |
165 | 203 | | |
166 | 204 | | |
| |||
178 | 216 | | |
179 | 217 | | |
180 | 218 | | |
181 | | - | |
| 219 | + | |
182 | 220 | | |
183 | 221 | | |
184 | 222 | | |
| |||
189 | 227 | | |
190 | 228 | | |
191 | 229 | | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
192 | 239 | | |
193 | 240 | | |
194 | 241 | | |
| |||
227 | 274 | | |
228 | 275 | | |
229 | 276 | | |
230 | | - | |
| 277 | + | |
| 278 | + | |
231 | 279 | | |
232 | 280 | | |
233 | 281 | | |
| |||
288 | 336 | | |
289 | 337 | | |
290 | 338 | | |
291 | | - | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
292 | 343 | | |
293 | 344 | | |
294 | 345 | | |
295 | 346 | | |
| 347 | + | |
| 348 | + | |
296 | 349 | | |
297 | | - | |
298 | 350 | | |
299 | 351 | | |
300 | 352 | | |
| |||
0 commit comments