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
);
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)) {
ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ);
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);
}
}
this.taskScheduler.setShutdown(true);
}
void ensureInAutosave(final NewChunkHolder holder) {

View File

@@ -271,6 +271,16 @@ public final class ChunkTaskScheduler {
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) {
this.world = world;
// 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;
}
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 int ticketLevel = getTicketLevel(status);
this.chunkHolderManager.addTicketAtLevel(NON_FULL_CHUNK_LOAD, chunkX, chunkZ, ticketLevel, ticketId);