Fire purge IslandEvents on the main thread - #3077
Merged
Merged
Conversation
PurgeRegionsService.delete() is dispatched from an async task by both the admin purge command and the housekeeping auto-purge, but it fired IslandEvent (DELETED / PURGED) directly from that thread. Paper rejects synchronous events fired off the main thread, so the age sweep crashed with "IslandEvent may only be triggered synchronously" after the region files had already been deleted, leaving island DB rows orphaned and reporting the purge as failed. Split delete() into two phases: disk I/O (region files, residual check, player data) stays on the calling thread, and the event firing plus cache/database removal is hopped onto the main thread via the scheduler and awaited, so the return value and summary log still reflect the final state. When already on the main thread the finalization runs inline. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZRwXXfTUJLJFwSnzSgeRb
|
Merged
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.



Problem
Reported on Discord by a server admin running BentoBox 3.22.3 on Paper 26.2:
/sgadmin purge confirmfails withLogs: https://mclo.gs/uGuzB8F, https://mclo.gs/rSn4KGX
PurgeRegionsService.delete()is dispatched from an async task by bothAbstractPurgeCommand.deleteEverything()andHousekeepingManager, but it fired theDELETED/PURGEDIslandEvents straight from that thread. Paper enforces that synchronous events are only fired on the main thread. Because the region files are deleted before the island loop, the crash left the region files gone but the island DB rows and cache entries intact, and the command reported the purge as failed.Fix
delete()is now two phases:finalizeIslands()firesDELETED(if the island was never soft-deleted) andPURGED, and removes the island from the cache and database. This is scheduled withrunTaskand awaited via aCompletableFuture, so the boolean return and the "Purge complete" summary log still reflect the final state. When already on the main thread it runs inline.The deleted sweep (
days == 0) still defers DB rows to shutdown and never touches the scheduler.Tests
testDeleteOffMainThreadFinalizesViaScheduler– withisPrimaryThread()false, verifies finalization goes through the scheduler, the cache/DB are cleaned, andDELETEDthenPURGEDfire in order.testDeleteOffMainThreadDeletedSweepDoesNotSchedule– deleted sweep off-thread never schedules or fires events.PurgeRegionsServiceTestcases now stubisPrimaryThread()true to keep exercising the inline path.Full suite: 3484 tests, 0 failures.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XZRwXXfTUJLJFwSnzSgeRb