fix: prevent ~2.5-min world-exit freeze after teleporting far along the train - #579
Open
bh679 wants to merge 3 commits into
Open
fix: prevent ~2.5-min world-exit freeze after teleporting far along the train#579bh679 wants to merge 3 commits into
bh679 wants to merge 3 commits into
Conversation
…he train Leaving a world (go-to-title / board-anew / quit) after teleporting far along the +X corridor froze the client ~158s. The world-exit pre-drain (DeathScreenLayoutHandler.preDrainTrainSubLevels) busy-spun container.tick() but never reflectively evicted leaked Sable PlotChunkHolders, so the integrated-server stopServer wait loop spun on ChunkMap.hasWork()=true (same class as Sable #679). - Extract the proven Sable #679 drain from ShipShutdownEvents into a shared TrainSubLevelTeardown helper: delete trains -> bounded pump -> reflective PlotChunkHolder sweep -> vanilla-holder drain after pre-save. - preDrainTrainSubLevels now runs that hardened drain with a 3s global server-thread pump budget (under the existing 10s client give-up); the sweep/drain run even when pump is squeezed to 0, so hasWork() can go false. - ShipShutdownEvents refactored to delegate to the shared helper (no behaviour change at ServerStopping). - Demote Trains.byTrainId DEBUG log to TRACE (~471 lines/s during teleport burst). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Leaving a Dungeon Train world (go-to-title / Board anew / Quit Game) after the player
has teleported/travelled far along the +X corridor froze the client for ~158 s before it
recovered, ending with
DeathScreenLayout: pre-drain wait timed out→TimeoutExceptionatpreDrainTrainSubLevels.Root cause — a pre-existing Sable teardown hang (same class as the known Save-and-Quit hang
= Sable #679). The world-exit pre-drain busy-spun
container.tick()for ~1 s/level but neverreflectively evicted the
PlotChunkHolders that leak past that drain, so the integrated-serverstopServerwait loop spun onChunkMap.hasWork() == true. The repo already had the proven fix,but only on the
ServerStoppingpath (ShipShutdownEvents). This makes the world-exit path usethe same hardened drain.
Changes
event/TrainSubLevelTeardown.java— the proven Sable feat: Books-written tally on the death screen #679 drain extracted fromShipShutdownEvents: delete trains → bounded pump → reflectivePlotChunkHoldersweep →vanilla-holder drain (after
save(flush=true)). Shared by both teardown paths.event/ShipShutdownEvents.java— refactored to a thinServerStoppingsubscriber delegatingto the helper (no behaviour change; ~249 → ~80 lines).
client/DeathScreenLayoutHandler.java—preDrainTrainSubLevelsnow runs the hardened drainwith a 3 s global server-thread pump budget (under the existing 10 s client give-up). The
sweep/drain run even when pump is squeezed to 0 — that's what lets
hasWork()go false. Coversall three callers (go-to-title, board-anew, quit-to-desktop).
train/Trains.java—byTrainIdlog demoted DEBUG → TRACE (was ~471 lines/s during theteleport burst).
Mod-impact
No new deps, no version/mixin/registry/worldgen/networking changes. Touches Sable teardown timing
only. Reflective
updatingChunkMapaccess is the same already-shipped technique asShipShutdownEvents/ShutdownDiagnostics(try/catch → warn, never throws).Test plan
./gradlew build— green; all 88 unit-test classes pass../gradlew runClient— loads clean to title; a real world-exit ran the new path anddrained 2360 vanilla ChunkHolders with no
pre-drain wait timed outand an immediateServerStopped./tp @s ~3000 ~ ~, ride to spawn carriages, then go-to-title) — expectswept N PlotChunkHoldersand a ~1–3 s return to title (no freeze). Sable: exercised on themoving train.
🤖 Generated with Claude Code