3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-08 17:20:24 +01:00

Improve shutdown of executor loader and mappings cache

Previously, the shutdown check would only happen once all futures were removed, as in a player joined that had to check the remaining protocols.
Now, the check will be done regularly once the plugin has fully been enabled and has the option to delay the shutdown until set on again (i.e. with ViaBackwards)
Dieser Commit ist enthalten in:
KennyTV 2020-04-24 13:27:29 +02:00
Ursprung 4b9a15b003
Commit e4bac5f81a
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
3 geänderte Dateien mit 38 neuen und 7 gelöschten Zeilen

Datei anzeigen

@ -2,6 +2,7 @@ package us.myles.ViaVersion;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.TaskId;
import us.myles.ViaVersion.api.platform.ViaConnectionManager; import us.myles.ViaVersion.api.platform.ViaConnectionManager;
import us.myles.ViaVersion.api.platform.ViaInjector; import us.myles.ViaVersion.api.platform.ViaInjector;
import us.myles.ViaVersion.api.platform.ViaPlatform; import us.myles.ViaVersion.api.platform.ViaPlatform;
@ -27,6 +28,7 @@ public class ViaManager {
private final ViaCommandHandler commandHandler; private final ViaCommandHandler commandHandler;
private final ViaPlatformLoader loader; private final ViaPlatformLoader loader;
private final Set<String> subPlatforms = new HashSet<>(); private final Set<String> subPlatforms = new HashSet<>();
private TaskId mappingLoadingTask;
private boolean debug; private boolean debug;
public ViaManager(ViaPlatform<?> platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) { public ViaManager(ViaPlatform<?> platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
@ -86,6 +88,12 @@ public class ViaManager {
// Load Platform // Load Platform
loader.load(); loader.load();
// Common tasks // Common tasks
mappingLoadingTask = Via.getPlatform().runRepeatingSync(() -> {
if (ProtocolRegistry.checkForMappingCompletion()) {
platform.cancelTask(mappingLoadingTask);
mappingLoadingTask = null;
}
}, 10L);
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) { if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (Via.getConfig().isSimulatePlayerTick()) { if (Via.getConfig().isSimulatePlayerTick()) {
Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L); Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);

Datei anzeigen

@ -6,6 +6,7 @@ import com.google.gson.JsonIOException;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.util.GsonUtil; import us.myles.ViaVersion.util.GsonUtil;
import java.io.File; import java.io.File;
@ -33,6 +34,7 @@ public class MappingDataLoader {
public static void enableMappingsCache() { public static void enableMappingsCache() {
cacheJsonMappings = true; cacheJsonMappings = true;
ProtocolRegistry.setKeepExecutorLoaded(true);
} }
/** /**

Datei anzeigen

@ -61,6 +61,7 @@ public class ProtocolRegistry {
private static Map<Class<? extends Protocol>, CompletableFuture<Void>> mappingLoaderFutures = new HashMap<>(); private static Map<Class<? extends Protocol>, CompletableFuture<Void>> mappingLoaderFutures = new HashMap<>();
private static ThreadPoolExecutor mappingLoaderExecutor; private static ThreadPoolExecutor mappingLoaderExecutor;
private static boolean mappingsLoaded; private static boolean mappingsLoaded;
private static boolean keepExecutorLoaded;
static { static {
mappingLoaderExecutor = new ThreadPoolExecutor(5, 16, 45L, TimeUnit.SECONDS, new SynchronousQueue<>()); mappingLoaderExecutor = new ThreadPoolExecutor(5, 16, 45L, TimeUnit.SECONDS, new SynchronousQueue<>());
@ -70,11 +71,10 @@ public class ProtocolRegistry {
registerBaseProtocol(BASE_PROTOCOL, Range.lessThan(Integer.MIN_VALUE)); registerBaseProtocol(BASE_PROTOCOL, Range.lessThan(Integer.MIN_VALUE));
registerBaseProtocol(new BaseProtocol1_7(), Range.all()); registerBaseProtocol(new BaseProtocol1_7(), Range.all());
// Register built in protocols
registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_9, ProtocolVersion.v1_8); registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_9, ProtocolVersion.v1_8);
registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId()); registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
registerProtocol(new Protocol1_9_3To1_9_1_2(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_9_2); registerProtocol(new Protocol1_9_3To1_9_1_2(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_9_2);
// Only supported for 1.9.4 server to 1.9 (nothing else)
registerProtocol(new Protocol1_9To1_9_1(), ProtocolVersion.v1_9, ProtocolVersion.v1_9_2); registerProtocol(new Protocol1_9To1_9_1(), ProtocolVersion.v1_9, ProtocolVersion.v1_9_2);
registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId()); registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId());
registerProtocol(new Protocol1_10To1_9_3_4(), ProtocolVersion.v1_10, ProtocolVersion.v1_9_3); registerProtocol(new Protocol1_10To1_9_3_4(), ProtocolVersion.v1_10, ProtocolVersion.v1_9_3);
@ -320,15 +320,26 @@ public class ProtocolRegistry {
if (future == null) return; if (future == null) return;
future.get(); future.get();
synchronized (MAPPING_LOADER_LOCK) {
if (mappingsLoaded) return;
// Remove only after execution to block other potential threads
mappingLoaderFutures.remove(protocolClass);
if (mappingLoaderFutures.isEmpty()) {
shutdownLoaderExecutor();
} }
/**
* Shuts down the executor and uncaches mappings if all futures have been completed.
*
* @return true if the executor has now been shut down
*/
public static boolean checkForMappingCompletion() {
synchronized (MAPPING_LOADER_LOCK) {
if (mappingsLoaded || keepExecutorLoaded) return false;
for (CompletableFuture<Void> future : mappingLoaderFutures.values()) {
// Return if any future hasn't completed yet
if (!future.isDone()) {
return false;
}
}
shutdownLoaderExecutor();
return true;
} }
} }
@ -336,6 +347,7 @@ public class ProtocolRegistry {
mappingsLoaded = true; mappingsLoaded = true;
mappingLoaderExecutor.shutdown(); mappingLoaderExecutor.shutdown();
mappingLoaderExecutor = null; mappingLoaderExecutor = null;
mappingLoaderFutures.clear();
mappingLoaderFutures = null; mappingLoaderFutures = null;
if (MappingDataLoader.isCacheJsonMappings()) { if (MappingDataLoader.isCacheJsonMappings()) {
MappingDataLoader.getMappingsCache().clear(); MappingDataLoader.getMappingsCache().clear();
@ -355,4 +367,13 @@ public class ProtocolRegistry {
return mappingLoaderFutures.get(protocolClass); return mappingLoaderFutures.get(protocolClass);
} }
} }
/**
* If set to true, the executor and mappings will stay loaded, even if all current futures have been completed.
*
* @param keepExecutorLoaded whether to keep the executor and mappings loaded, even if all current futures have been completed
*/
public static void setKeepExecutorLoaded(boolean keepExecutorLoaded) {
ProtocolRegistry.keepExecutorLoaded = keepExecutorLoaded;
}
} }