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:
co-authored by
Claude Opus 4.8
parent
2f4b2f9e91
commit
117b92cb24
+4
-2
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user