Relay: snapshot by_host in the PEER_UP/DOWN fanouts (end-of-round crash)

When every pod disconnects at once (normal end of a multiplayer round),
a failed send inside the PEER_DOWN fanout recursively drops that peer
and mutates by_host mid-iteration -> RuntimeError -> THE RELAY DIES,
taking the round reset and the matchlog uploads with it (live crash,
first 3-player internet round).  Iterate over snapshots.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-22 22:03:16 -05:00
co-authored by Claude Opus 4.8
parent 2f4b2f9e91
commit 117b92cb24
+4 -2
View File
@@ -923,7 +923,8 @@ class Relay:
for other_id in sorted(self.by_host):
if other_id != host_id:
self._send_control(conn, ROUTE_PEER_UP, other_id)
for other in self.by_host.values():
for other in list(self.by_host.values()): # snapshot: a failed
# send drops that peer INSIDE the loop (mutates by_host)
if other is not conn:
self._send_control(other, ROUTE_PEER_UP, host_id)
return
@@ -990,7 +991,8 @@ class Relay:
if conn.host_id is not None and self.by_host.get(conn.host_id) is conn:
del self.by_host[conn.host_id]
self.udp_endpoint.pop(conn.host_id, None)
for other in self.by_host.values():
for other in list(self.by_host.values()): # snapshot: a failed
# send drops that peer INSIDE the loop (mutates by_host)
self._send_control(other, ROUTE_PEER_DOWN, conn.host_id)
self._maybe_reset_round()