Skip to content

Commit

Permalink
Fixed purging islands making the server hang out when disabling it (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
OmerBenGera committed Dec 2, 2022
1 parent ce62682 commit 35efb9c
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 27 deletions.
Expand Up @@ -324,11 +324,12 @@ public void onEnable() {

@Override
public void onDisable() {
BukkitExecutor.prepareDisable();

if (!shouldEnable)
return;

ChunksProvider.stop();
BukkitExecutor.syncDatabaseCalls();

try {
dataHandler.saveDatabase(false);
Expand Down Expand Up @@ -363,12 +364,12 @@ public void onDisable() {
Log.info("Shutting down calculation task...");
CalcTask.cancelTask();

Log.info("Shutting down executor");
BukkitExecutor.close();

if (nmsChunks != null)
nmsChunks.shutdown();

Log.info("Shutting down executor");
BukkitExecutor.close();

Log.info("Closing database. This may hang the server. Do not shut it down, or data may get lost.");
dataHandler.closeConnection();
}
Expand Down
Expand Up @@ -19,6 +19,7 @@ public class BukkitExecutor {
private static ExecutorService databaseExecutor;
private static boolean shutdown = false;
private static boolean syncDatabaseCalls = false;
private static boolean syncBukkitCalls = false;

private BukkitExecutor() {

Expand All @@ -30,32 +31,34 @@ public static void init(SuperiorSkyblockPlugin plugin) {
}

public static void ensureMain(Runnable runnable) {
if (shutdown)
if (ensureNotShudown())
return;

if (!Bukkit.isPrimaryThread()) {
if (!syncBukkitCalls && !Bukkit.isPrimaryThread()) {
sync(runnable);
} else {
runnable.run();
}
}

public static BukkitTask sync(Runnable runnable) {
if (shutdown)
return null;

return sync(runnable, 0);
}

public static BukkitTask sync(Runnable runnable, long delay) {
if (shutdown)
if (ensureNotShudown())
return null;

return Bukkit.getScheduler().runTaskLater(plugin, runnable, delay);
if (syncBukkitCalls) {
runnable.run();
return null;
} else {
return Bukkit.getScheduler().runTaskLater(plugin, runnable, delay);
}
}

public static void data(Runnable runnable) {
if (shutdown)
if (ensureNotShudown())
return;

if (syncDatabaseCalls) {
Expand All @@ -70,28 +73,36 @@ public static boolean isDataThread() {
}

public static void async(Runnable runnable) {
if (shutdown)
if (ensureNotShudown())
return;

Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable);
if (syncBukkitCalls) {
runnable.run();
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable);
}
}

public static void async(Runnable runnable, long delay) {
if (shutdown)
if (ensureNotShudown())
return;

Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay);
if (syncBukkitCalls) {
runnable.run();
} else {
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay);
}
}

public static void asyncTimer(Runnable runnable, long delay) {
if (shutdown)
if (ensureNotShudown())
return;

Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, delay);
}

public static void timer(Runnable runnable, long delay) {
if (shutdown)
if (ensureNotShudown())
return;

Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, delay);
Expand All @@ -101,8 +112,9 @@ public static NestedTask<Void> createTask() {
return new NestedTask<Void>().complete();
}

public static void syncDatabaseCalls() {
public static void prepareDisable() {
syncDatabaseCalls = true;
syncBukkitCalls = true;
}

public static void close() {
Expand All @@ -115,6 +127,15 @@ public static void close() {
}
}

private static boolean ensureNotShudown() {
if (shutdown) {
new RuntimeException("Tried to call BukkitExecutor after it was shut down").printStackTrace();
return true;
}

return false;
}

private static void shutdownAndAwaitTermination() {
databaseExecutor.shutdown(); // Disable new tasks from being submitted
try {
Expand Down Expand Up @@ -142,31 +163,49 @@ public static class NestedTask<T> {

public <R> NestedTask<R> runSync(Function<T, R> function) {
NestedTask<R> nestedTask = new NestedTask<>();
value.whenComplete((value, ex) -> BukkitExecutor.ensureMain(() -> nestedTask.value.complete(function.apply(value))));
if (syncBukkitCalls) {
nestedTask.value.complete(function.apply(value.join()));
} else {
value.whenComplete((value, ex) -> BukkitExecutor.ensureMain(() -> nestedTask.value.complete(function.apply(value))));
}
return nestedTask;
}

public NestedTask<Void> runSync(Consumer<T> consumer) {
NestedTask<Void> nestedTask = new NestedTask<>();
value.whenComplete((value, ex) -> BukkitExecutor.ensureMain(() -> {
consumer.accept(value);
if (syncBukkitCalls) {
consumer.accept(value.join());
nestedTask.value.complete(null);
}));
} else {
value.whenComplete((value, ex) -> BukkitExecutor.ensureMain(() -> {
consumer.accept(value);
nestedTask.value.complete(null);
}));
}
return nestedTask;
}

public <R> NestedTask<R> runAsync(Function<T, R> function) {
NestedTask<R> nestedTask = new NestedTask<>();
value.whenComplete((value, ex) -> BukkitExecutor.async(() -> nestedTask.value.complete(function.apply(value))));
if (syncBukkitCalls) {
nestedTask.value.complete(function.apply(value.join()));
} else {
value.whenComplete((value, ex) -> BukkitExecutor.async(() -> nestedTask.value.complete(function.apply(value))));
}
return nestedTask;
}

public NestedTask<Void> runAsync(Consumer<T> consumer) {
NestedTask<Void> nestedTask = new NestedTask<>();
value.whenComplete((value, ex) -> BukkitExecutor.async(() -> {
consumer.accept(value);
if (syncBukkitCalls) {
consumer.accept(value.join());
nestedTask.value.complete(null);
}));
} else {
value.whenComplete((value, ex) -> BukkitExecutor.async(() -> {
consumer.accept(value);
nestedTask.value.complete(null);
}));
}
return nestedTask;
}

Expand Down

0 comments on commit 35efb9c

Please sign in to comment.