Abort join point creation when host disconnects#863
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a server-side escape hatch to end an in-progress join point when the host disconnects, preventing reconnects from getting stuck waiting in ServerLoading (Fixes #860).
Changes:
- Introduces
WorldData.AbortJoinPointCreation()to complete pendingWaitJoinPoint()waiters without swapping the current snapshot. - Calls abort logic from
PlayerManager.SetDisconnected()when the host disconnects during join point creation, with a diagnostic log line. - Adds a regression test ensuring aborting a join point unblocks
WaitJoinPoint().
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Source/Tests/ServerTest.cs | Adds a regression test that verifies aborting join point creation releases waiters. |
| Source/Common/WorldData.cs | Adds abort API and clears the join point TCS on completion/abort to unblock WaitJoinPoint(). |
| Source/Common/PlayerManager.cs | Hooks host disconnect to abort join point creation and logs the action. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Players.Remove(player); | ||
|
|
||
| if (player.IsHost && server.worldData.CreatingJoinPoint) | ||
| { | ||
| server.worldData.AbortJoinPointCreation(); | ||
| ServerLog.Log("Aborted join point creation because the host disconnected."); |
There was a problem hiding this comment.
SetDisconnected aborts join point creation only when the disconnected player is IsHost. In arbiter mode, join point creation uploads are accepted only from the arbiter (Server.ArbiterPlaying ? Player.IsArbiter : Player.IsHost in ServerPlayingState.HandleWorldDataUpload), so if the arbiter disconnects during an in-progress join point the server can still remain stuck in CreatingJoinPoint and keep ServerLoadingState waiters blocked. Consider aborting when the disconnecting player is the current join point upload source (host vs arbiter), and note that you may need to capture the arbiter/host mode before Players.Remove(player) so the decision isn't affected by the removal.
| Players.Remove(player); | |
| if (player.IsHost && server.worldData.CreatingJoinPoint) | |
| { | |
| server.worldData.AbortJoinPointCreation(); | |
| ServerLog.Log("Aborted join point creation because the host disconnected."); | |
| bool arbiterPlaying = server.ArbiterPlaying; | |
| bool isJoinPointUploadSource = arbiterPlaying ? player.IsArbiter : player.IsHost; | |
| Players.Remove(player); | |
| if (isJoinPointUploadSource && server.worldData.CreatingJoinPoint) | |
| { | |
| server.worldData.AbortJoinPointCreation(); | |
| ServerLog.Log($"Aborted join point creation because the {(arbiterPlaying ? "arbiter" : "host")} disconnected."); |
|
As i seen arbiter is not supported for standalone server(i may be wrong) |
|
Arbiter has been disabled for a while. It causes issues, specially when evaluating camera. |
Summary
Abort an in-progress join point when the host disconnects so reconnect does not remain blocked in
ServerLoading.Fixes #860.
What changed
WorldData.AbortJoinPointCreation()to cleanly end a pending join point wait without replacing the current world snapshotPlayerManager.SetDisconnected()when the disconnected player is the hostWhy this fixes the issue
Previously, if the host disconnected during join point creation,
WorldData.CreatingJoinPointstayed active andServerLoadingkept waiting onWaitJoinPoint(). That prevented reconnect from progressing.After this change, disconnecting the host resets the pending join point creation and releases waiting loading states so reconnect can proceed against the last stable world snapshot.
Validation
dotnet build Source/Server/Server.csproj -c ReleaseServerTestregression passes