From 3ce0cb9dc1e7a835c3ea6eacc1eb992132d8e1eb Mon Sep 17 00:00:00 2001 From: swazrgb <65694696+swazrgb@users.noreply.github.com> Date: Sun, 24 May 2020 03:29:30 +0200 Subject: [PATCH] Shutdown ExecutorService in ExternalPluginManager Also name threads for easy identification --- .../client/plugins/ExternalPluginManager.java | 121 ++++++++++-------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ExternalPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/ExternalPluginManager.java index 05a5d9aa6c..34386310bd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ExternalPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ExternalPluginManager.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.inject.Binder; import com.google.inject.CreationException; import com.google.inject.Injector; @@ -685,72 +686,86 @@ public class ExternalPluginManager List scannedPlugins = new CopyOnWriteArrayList<>(); // some plugins get stuck on IO, so add some extra threads - ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); + ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2, + new ThreadFactoryBuilder() + .setNameFormat("plugin-manager-%d") + .build()); - for (Plugin plugin : plugins) + try { - Class clazz = plugin.getClass(); - PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class); - - try + for (Plugin plugin : plugins) { - if (pluginDescriptor == null) + Class clazz = plugin.getClass(); + PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class); + + try { - if (Plugin.class.isAssignableFrom(clazz)) + if (pluginDescriptor == null) { - log.warn("Class {} is a plugin, but has no plugin descriptor", clazz); + if (Plugin.class.isAssignableFrom(clazz)) + { + log.warn("Class {} is a plugin, but has no plugin descriptor", clazz); + } + continue; + } + else if (!Plugin.class.isAssignableFrom(clazz)) + { + log.warn("Class {} has plugin descriptor, but is not a plugin", clazz); + continue; + } + else if (!pluginTypes.contains(pluginDescriptor.type())) + { + continue; } - continue; } - else if (!Plugin.class.isAssignableFrom(clazz)) + catch (EnumConstantNotPresentException e) { - log.warn("Class {} has plugin descriptor, but is not a plugin", clazz); + log.warn("{} has an invalid plugin type of {}", clazz, e.getMessage()); continue; } - else if (!pluginTypes.contains(pluginDescriptor.type())) + + List> curGroup = new ArrayList<>(); + curGroup.add(exec.submit(() -> { - continue; - } + Plugin plugininst; + try + { + //noinspection unchecked + plugininst = instantiate(scannedPlugins, (Class) plugin.getClass(), init, initConfig); + scannedPlugins.add(plugininst); + } + catch (PluginInstantiationException e) + { + log.warn("Error instantiating plugin!", e); + return; + } + + loaded.getAndIncrement(); + + RuneLiteSplashScreen.stage(.67, .75, "Loading external plugins", loaded.get(), scannedPlugins.size()); + })); + curGroup.forEach(future -> + { + try + { + future.get(); + } + catch (InterruptedException | ExecutionException e) + { + e.printStackTrace(); + } + }); + } + } + finally + { + List unfinishedTasks = exec.shutdownNow(); + if (!unfinishedTasks.isEmpty()) + { + // This shouldn't happen since we Future#get all tasks submitted to the executor + log.warn("Did not complete all update tasks: {}", unfinishedTasks); } - catch (EnumConstantNotPresentException e) - { - log.warn("{} has an invalid plugin type of {}", clazz, e.getMessage()); - continue; - } - - List> curGroup = new ArrayList<>(); - curGroup.add(exec.submit(() -> - { - Plugin plugininst; - try - { - //noinspection unchecked - plugininst = instantiate(scannedPlugins, (Class) plugin.getClass(), init, initConfig); - scannedPlugins.add(plugininst); - } - catch (PluginInstantiationException e) - { - log.warn("Error instantiating plugin!", e); - return; - } - - loaded.getAndIncrement(); - - RuneLiteSplashScreen.stage(.67, .75, "Loading external plugins", loaded.get(), scannedPlugins.size()); - })); - curGroup.forEach(future -> - { - try - { - future.get(); - } - catch (InterruptedException | ExecutionException e) - { - e.printStackTrace(); - } - }); } - } @SuppressWarnings("unchecked")