Fix watched plugins reloading without ensuring the file has fully uploaded first (#8)
* build: add Apache codec library Utilise the Apache commons codec library, which has file hashing and checking functions. This will be useful for a fix on hotreloading plugins. * feat: run tasks later on taskmanagers Add the ability to run tasks at a later date on task managers. This is expressed in ticks for bungeecord and bukkit, and is converted to milliseconds for bungeecord. * feat: add method to get hash of file Add a method to get the MD5 hash of a file. * fix: watching plugins waits until the plugin has finished uploading If a watched plugin is changed, it will no longer immediately reload the plugin. Instead, it will check every 10 ticks (500 milliseconds for BungeeCord) to see if the file MD5 checksum has changed. If it hasn't, then we can presume the file upload has completed and reload the plugin. * build: bump version to 2.5.1 * build: relocate apache codec Relocate the Apache Codec to avoid dependency clashes * perf: remove unnecessary task call
This commit is contained in:
parent
5d227ac06e
commit
b51ff445dd
6 changed files with 75 additions and 19 deletions
|
|
@ -1,6 +1,15 @@
|
|||
package net.frankheijden.serverutils.common.tasks;
|
||||
|
||||
import com.sun.nio.file.SensitivityWatchEventModifier;
|
||||
import net.frankheijden.serverutils.common.ServerUtilsApp;
|
||||
import net.frankheijden.serverutils.common.entities.AbstractTask;
|
||||
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
|
||||
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
|
||||
import net.frankheijden.serverutils.common.entities.WatchResult;
|
||||
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
|
||||
import net.frankheijden.serverutils.common.managers.AbstractTaskManager;
|
||||
import net.frankheijden.serverutils.common.providers.ChatProvider;
|
||||
import net.frankheijden.serverutils.common.utils.FileUtils;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.ClosedWatchServiceException;
|
||||
|
|
@ -10,18 +19,10 @@ import java.nio.file.WatchEvent;
|
|||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import net.frankheijden.serverutils.common.ServerUtilsApp;
|
||||
import net.frankheijden.serverutils.common.entities.AbstractTask;
|
||||
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
|
||||
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
|
||||
import net.frankheijden.serverutils.common.entities.WatchResult;
|
||||
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
|
||||
import net.frankheijden.serverutils.common.managers.AbstractTaskManager;
|
||||
import net.frankheijden.serverutils.common.providers.ChatProvider;
|
||||
|
||||
public class PluginWatcherTask extends AbstractTask {
|
||||
|
||||
private static final WatchEvent.Kind<?>[] EVENTS = new WatchEvent.Kind[] {
|
||||
private static final WatchEvent.Kind<?>[] EVENTS = new WatchEvent.Kind[]{
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY,
|
||||
StandardWatchEventKinds.ENTRY_DELETE
|
||||
|
|
@ -37,13 +38,16 @@ public class PluginWatcherTask extends AbstractTask {
|
|||
|
||||
private final ServerCommandSender sender;
|
||||
private final String pluginName;
|
||||
private File file;
|
||||
private final AtomicBoolean run;
|
||||
private File file;
|
||||
private String hash;
|
||||
|
||||
private WatchService watchService;
|
||||
private Object task = null;
|
||||
|
||||
/**
|
||||
* Constructs a new PluginWatcherTask for the specified plugin.
|
||||
*
|
||||
* @param pluginName The name of the plugin.
|
||||
*/
|
||||
public PluginWatcherTask(ServerCommandSender sender, String pluginName) {
|
||||
|
|
@ -65,12 +69,20 @@ public class PluginWatcherTask extends AbstractTask {
|
|||
WatchKey key = watchService.take();
|
||||
for (WatchEvent<?> event : key.pollEvents()) {
|
||||
if (file.getName().equals(event.context().toString())) {
|
||||
send(WatchResult.CHANGE);
|
||||
String previousHash = hash;
|
||||
hash = FileUtils.getHash(file);
|
||||
if (task != null) {
|
||||
//noinspection unchecked
|
||||
taskManager.cancelTask(task);
|
||||
}
|
||||
task = ServerUtilsApp.getPlugin().getTaskManager().runTaskLater(() -> {
|
||||
if (hash.equals(previousHash)) {
|
||||
send(WatchResult.CHANGE);
|
||||
|
||||
taskManager.runTask(() -> {
|
||||
pluginManager.reloadPlugin(pluginName);
|
||||
file = pluginManager.getPluginFile(pluginName);
|
||||
});
|
||||
pluginManager.reloadPlugin(pluginName);
|
||||
file = pluginManager.getPluginFile(pluginName);
|
||||
}
|
||||
}, 10L);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue