Ship Respawn Guard on Service Restart
Problem
When the physics service restarts, ships get respawned at their default position with full fuel, destroying in-progress maneuvers. This happens because:
- Player’s WebSocket reconnects after service restart, triggering re-login
- Players service calls
_check_ship_exists→GetShipStateon physics - If
GetShipStatefails for ANY reason (gRPC error, proto mismatch, timeout),_check_ship_existsreturnsFalse - Players service calls
SpawnShip→ overwrites the ship in Redis at spawn position with full fuel - Ship’s in-progress position, velocity, fuel, and maneuver state are lost
The ship data was safe in Redis the entire time — it was the SpawnShip call
that destroyed it.
Root Cause
Two issues contribute:
-
SpawnShipunconditionally overwrites: No check for whether the ship already exists in Redis. A spawn request for an existing ship should be a no-op (return existing state). -
_check_ship_existstreats all errors as “missing”: Any gRPC error (including proto mismatches, timeouts, service unavailable) is caught and returnsFalse, triggering a respawn.
Fix
1. Guard SpawnShip against existing ships (physics service)
In simulation.py spawn_ship(), check Redis for an existing ship with the
same ship_id before creating a new one. If found, return the existing ship
without modification.
2. Distinguish NOT_FOUND from errors (players service)
In _check_ship_exists, only return False for an actual NOT_FOUND gRPC
status. For all other errors (UNAVAILABLE, UNKNOWN, DEADLINE_EXCEEDED, etc.),
raise the exception so the caller doesn’t trigger a respawn.