Fix: player session never recovers when server resets - #18
Conversation
… connecting fails 3 times
2c598a9 to
7a8c616
Compare
a149dc3 to
f72fbea
Compare
jbriones1
left a comment
There was a problem hiding this comment.
The test comments can probably be ignored, but when tests are sus I'm sus of the code.
| }); | ||
|
|
||
| it('re-registers with the saved name and reconnects', async () => { | ||
| playerName.get.mockReturnValue('Odin'); |
|
|
||
| const startCalls = gameSocket.start.mock.calls; | ||
| const onConnected = startCalls[startCalls.length - 1][1] as () => void; | ||
| expect(startCalls[startCalls.length - 1][0]).toBe('NEWID'); |
There was a problem hiding this comment.
nit: this doesn't check the third argument of the start function. In the future, if someone refactors and messes up and doesn't add a third parameter on reconnect this test would fail.
|
|
||
| protected override shouldReconnect(closeEvent: CloseEvent): boolean { | ||
| if (this.mode !== 'player') { | ||
| return true; |
There was a problem hiding this comment.
I don't think players should reconnect if the closeEvent was graceful (status 1001). I don't think our server is capable of having a good shutdown, so maybe this could be added.
With this logic, if server is shut down and someone never closed their browser tab, they would reconnect if the server was turned back and they opened their tab. Would be kinda weird.
There was a problem hiding this comment.
Server shutdown now sends an explicit shutdown command soclient can now distinguish between intentional game shutdown from the other 1001 graceful closes
|
Will take a look at how to get the server to explicitly send signals instead of frontend guessing when to reconnect so we're not retrying connection even on graceful server shutdowns! |
bdb0c24 to
461f103
Compare
jbriones1
left a comment
There was a problem hiding this comment.
Maybe I don't understand it, the control functions should only be used for shutdowns, not anything else. Also, I'll need to confirm the Websocket 1001 close message, because I'm not sure this does it.
| message, ok := informMessage(player, coordinate) | ||
| if ok { | ||
| h.broadcast(message, nil, onlyViewers) | ||
| h.broadcastControl(message, nil, onlyViewers) |
There was a problem hiding this comment.
This seems dangerous. Other player messages could be waiting in the queue to be written, but someone disconnecting could remove all those messages. I think this should be a normal broadcast.
| outgoing = message | ||
| } | ||
| if !h.enqueue(connection, outgoing) { | ||
| if !h.enqueueControl(connection, outgoing) { |
There was a problem hiding this comment.
Same as above, other messages can still be relevant.
| message, ok := informMessage(player, coordinate) | ||
| if ok { | ||
| h.broadcast(message, nil, onlyViewers) | ||
| h.broadcastControl(message, nil, onlyViewers) |
There was a problem hiding this comment.
Same as above, other messages can still be relevant.
| // Block until SIGINT (Ctrl+C) or SIGTERM (systemd stop/restart). | ||
| quit := make(chan os.Signal, 1) | ||
| signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) | ||
| <-quit | ||
|
|
||
| fmt.Println("Shutdown signal received. Notifying players...") | ||
| sock.BroadcastShutDown(api.CMD_SHUTDOWN) | ||
|
|
||
| // Give write pumps ~1 second to flush the shutdown message before exiting. | ||
| time.Sleep(1 * time.Second) | ||
| fmt.Println("Server exiting.") |
There was a problem hiding this comment.
This seems suspicious since:
- The HTTP listener is still active while shutting down, so new connections can be accepted while attempting to shut down.
- It sleeps for 1 second, which is arbitrary, a deadline for WriteControl should be used instead.
- It doesn't wait for the write pumps to complete.
- It doesn't hit the admin or leader websocket, I think.
- I've never used this websocket library before, but I don't think users get 1001 when the server shuts down. I'll need to double-check this.
|
closing this bc im a dumbass |

Closes #12
Description:
Server restarting previously left players stuck on "Reconnecting.,,"because the browser still had player ID cookie, but the restarted server no longer had the corresponding player session. To fix this: