MySQL databases were not saving properly on shutdown.

Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1292
This commit is contained in:
tastybento 2020-04-20 18:37:42 -07:00
parent 91ccf51a54
commit 88b331d1e4
4 changed files with 46 additions and 34 deletions

View File

@ -91,6 +91,8 @@ public class BentoBox extends JavaPlugin {
private BukkitTask blueprintLoadingTask;
private boolean shutdown;
@Override
public void onEnable(){
if (!ServerCompatibility.getInstance().checkCompatibility().isCanLaunch()) {
@ -193,8 +195,8 @@ public class BentoBox extends JavaPlugin {
flagsManager.registerListeners();
// Load metrics
metrics = new BStats(this);
metrics.registerMetrics();
metrics = new BStats(this);
metrics.registerMetrics();
// Register Multiverse hook - MV loads AFTER BentoBox
// Make sure all worlds are already registered to Multiverse.
@ -273,6 +275,8 @@ public class BentoBox extends JavaPlugin {
if (islandsManager != null) {
islandsManager.shutdown();
}
// Close all async database tasks
shutdown = true;
}
/**
@ -495,4 +499,13 @@ public class BentoBox extends JavaPlugin {
public void reloadConfig() {
loadSettings();
}
/**
* Check if plug has shutdown. Used to close databases that are running async.
* @return true if plugin has shutdown
* @since 1.13.0
*/
public boolean isShutdown() {
return shutdown;
}
}

View File

@ -74,15 +74,15 @@ public class AdminRangeSetCommand extends CompositeCommand {
// Well, now it can be applied without taking any risks!
island.setProtectionRange(range);
// Call Protection Range Change event. Does not support cancelling.
// Call Protection Range Change event. Does not support canceling.
IslandEvent.builder()
.island(island)
.location(island.getCenter())
.reason(IslandEvent.Reason.RANGE_CHANGE)
.involvedPlayer(targetUUID)
.admin(true)
.protectionRange(range, oldRange)
.build();
.island(island)
.location(island.getCenter())
.reason(IslandEvent.Reason.RANGE_CHANGE)
.involvedPlayer(targetUUID)
.admin(true)
.protectionRange(range, oldRange)
.build();
user.sendMessage("commands.admin.range.set.success", TextVariables.NUMBER, String.valueOf(range));

View File

@ -95,32 +95,30 @@ public abstract class AbstractDatabaseHandler<T> {
this.databaseConnector = databaseConnector;
this.dataObject = type;
// Return if plugin disabled
if (!plugin.isEnabled()) return;
// Run async queue
processQueue = new ConcurrentLinkedQueue<>();
if (plugin.isEnabled()) {
asyncSaveTask = Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
// Loop continuously
while (!shutdown || !processQueue.isEmpty()) {
// This catches any databases that are not explicitly closed
if (!plugin.isEnabled()) {
shutdown = true;
}
while (!processQueue.isEmpty()) {
processQueue.poll().run();
}
// Clear the queue and then sleep
try {
Thread.sleep(25);
} catch (InterruptedException e) {
plugin.logError("Thread sleep error " + e.getMessage());
Thread.currentThread().interrupt();
}
asyncSaveTask = Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
// Loop continuously
while (!shutdown || !processQueue.isEmpty()) {
while (!processQueue.isEmpty()) {
processQueue.poll().run();
}
// Cancel
asyncSaveTask.cancel();
databaseConnector.closeConnection(dataObject);
});
}
// Shutdown flag
shutdown = plugin.isShutdown();
// Clear the queue and then sleep
try {
Thread.sleep(25);
} catch (InterruptedException e) {
plugin.logError("Thread sleep error " + e.getMessage());
Thread.currentThread().interrupt();
}
}
// Cancel
asyncSaveTask.cancel();
databaseConnector.closeConnection(dataObject);
});
}
protected AbstractDatabaseHandler() {}
@ -173,4 +171,5 @@ public abstract class AbstractDatabaseHandler<T> {
* @since 1.1
*/
public abstract void deleteID(String uniqueId);
}

View File

@ -304,7 +304,7 @@ public class YamlDatabaseHandlerTest {
Mockito.verify(scheduler).runTaskAsynchronously(Mockito.eq(plugin), registerLambdaCaptor.capture());
Runnable lamda = registerLambdaCaptor.getValue();
// Cannot run with true otherwise it'll infinite loop
when(plugin.isEnabled()).thenReturn(false);
when(plugin.isShutdown()).thenReturn(true);
lamda.run();
Mockito.verify(task).cancel();