Add clean shutdown to Socks5Server test utility, fix a CI failure.
Closes #34849.
The Socks5Server utility handles multiple incoming connections, which are handled in separate background threads. Its stop() method unblocks and waits for the main background thread cleanly, but it doesn’t attempt to wait for the completion of handler threads. There is no guarantee that the handler threads are finished after stop() returns, which can lead to IO errors.
In the reported sporadic test failures, the test in p2p_private_broadcast.py uses the Socks5 server, and makes a node connect to/through it. Then it stops the Socks5 server, and then it stops the node. However, if a connection handler is still active, that can lead to errors, as the socket is closed.
The change attempts to fix this by storing all handler threads and connections, and attempting to shut them down before stop() returns.
Notes:
- I was not able to reliably reproduce the failure locally. The best attempt was to add a 0.25s sleep to
Socks5Connection.handle(), right after theself.serv.queue.put(cmdin)line. - With this change, in the
p2p_private_broadcast.pytest there are some handler threads that can’t be joined cleanly, even with the forced close of sockets, the join times out (after 2s). As a result, the test execution time has increased by several seconds.