Throw when sync loading chunks after shutdown

The caller would block indefinitely if a sync load is requested
during shutdown. Rather than block indefinitely, we should throw
an exception to indicate to the caller that the chunk system is
unable to process requests.
This commit is contained in:
Spottedleaf
2024-12-02 23:13:22 -08:00
parent 4bd7eb8b72
commit 93b908350e
3 changed files with 26 additions and 0 deletions

View File

@@ -86,6 +86,13 @@ abstract class ServerChunkCacheMixin extends ChunkSource implements ChunkSystemS
completable::complete completable::complete
); );
if (!completable.isDone() && chunkTaskScheduler.hasShutdown()) {
throw new IllegalStateException(
"Chunk system has shut down, cannot process chunk requests in world '" + ca.spottedleaf.moonrise.common.util.WorldUtil.getWorldName(this.level) + "' at "
+ "(" + chunkX + "," + chunkZ + ") status: " + toStatus
);
}
if (TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) { if (TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) {
ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ); ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ);
this.mainThreadProcessor.managedBlock(completable::isDone); this.mainThreadProcessor.managedBlock(completable::isDone);

View File

@@ -219,6 +219,8 @@ public final class ChunkHolderManager {
LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex); LOGGER.error("Failed to close '" + type.name() + "' regionfile cache for world '" + WorldUtil.getWorldName(this.world) + "'", ex);
} }
} }
this.taskScheduler.setShutdown(true);
} }
void ensureInAutosave(final NewChunkHolder holder) { void ensureInAutosave(final NewChunkHolder holder) {

View File

@@ -271,6 +271,16 @@ public final class ChunkTaskScheduler {
return this.lockShift; return this.lockShift;
} }
private volatile boolean shutdown;
public boolean hasShutdown() {
return this.shutdown;
}
public void setShutdown(final boolean shutdown) {
this.shutdown = shutdown;
}
public ChunkTaskScheduler(final ServerLevel world) { public ChunkTaskScheduler(final ServerLevel world) {
this.world = world; this.world = world;
// must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift // must be >= region shift (in paper, doesn't exist) and must be >= ticket propagator section shift
@@ -525,6 +535,13 @@ public final class ChunkTaskScheduler {
return loaded; return loaded;
} }
if (this.hasShutdown()) {
throw new IllegalStateException(
"Chunk system has shut down, cannot process chunk requests in world '" + ca.spottedleaf.moonrise.common.util.WorldUtil.getWorldName(this.world) + "' at "
+ "(" + chunkX + "," + chunkZ + ") status: " + status
);
}
final Long ticketId = getNextNonFullLoadId(); final Long ticketId = getNextNonFullLoadId();
final int ticketLevel = getTicketLevel(status); final int ticketLevel = getTicketLevel(status);
this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId); this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId);