Skip to content

Commit 021ee03

Browse files
committed
perf: parallelize plugin loading and initialization tasks in startup reactor
1 parent 4fdc1b3 commit 021ee03

1 file changed

Lines changed: 63 additions & 31 deletions

File tree

core/src/main/java/hudson/PluginManager.java

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -582,46 +582,78 @@ public void run(Reactor session) throws Exception {
582582
TaskGraphBuilder g = new TaskGraphBuilder();
583583

584584
// schedule execution of loading plugins
585+
Map<String, org.jvnet.hudson.reactor.Handle> loadHandles = new HashMap<>();
585586
for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[0])) {
586-
g.followedBy().notFatal().attains(PLUGINS_PREPARED).add(String.format("Loading plugin %s v%s (%s)", p.getLongName(), p.getVersion(), p.getShortName()), reactor -> {
587-
try {
588-
p.resolvePluginDependencies();
589-
strategy.load(p);
590-
} catch (MissingDependencyException e) {
591-
failedPlugins.add(new FailedPlugin(p, e));
592-
activePlugins.remove(p);
593-
plugins.remove(p);
594-
p.releaseClassLoader();
595-
LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() });
596-
} catch (IOException e) {
597-
failedPlugins.add(new FailedPlugin(p, e));
598-
activePlugins.remove(p);
599-
plugins.remove(p);
600-
p.releaseClassLoader();
601-
throw e;
587+
List<org.jvnet.hudson.reactor.Handle> reqs = new ArrayList<>();
588+
for (PluginWrapper.Dependency dep : p.getDependencies()) {
589+
org.jvnet.hudson.reactor.Handle h = loadHandles.get(dep.shortName);
590+
if (h != null) {
591+
reqs.add(h);
602592
}
603-
});
593+
}
594+
595+
org.jvnet.hudson.reactor.Handle handle = g.requires(reqs.toArray(new org.jvnet.hudson.reactor.Handle[0]))
596+
.notFatal()
597+
.attains(PLUGINS_PREPARED)
598+
.add(String.format("Loading plugin %s v%s (%s)", p.getLongName(), p.getVersion(), p.getShortName()), reactor -> {
599+
try {
600+
p.resolvePluginDependencies();
601+
strategy.load(p);
602+
} catch (MissingDependencyException e) {
603+
failedPlugins.add(new FailedPlugin(p, e));
604+
activePlugins.remove(p);
605+
plugins.remove(p);
606+
p.releaseClassLoader();
607+
LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() });
608+
} catch (IOException e) {
609+
failedPlugins.add(new FailedPlugin(p, e));
610+
activePlugins.remove(p);
611+
plugins.remove(p);
612+
p.releaseClassLoader();
613+
throw e;
614+
}
615+
});
616+
loadHandles.put(p.getShortName(), handle);
604617
}
605618

606619
// schedule execution of initializing plugins
620+
Map<String, org.jvnet.hudson.reactor.Handle> initHandles = new HashMap<>();
607621
for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[0])) {
608-
g.followedBy().notFatal().attains(PLUGINS_STARTED).add("Initializing plugin " + p.getShortName(), reactor -> {
609-
if (!activePlugins.contains(p)) {
610-
return;
611-
}
612-
try {
613-
p.getPluginOrFail().postInitialize();
614-
} catch (Exception e) {
615-
failedPlugins.add(new FailedPlugin(p, e));
616-
activePlugins.remove(p);
617-
plugins.remove(p);
618-
p.releaseClassLoader();
619-
throw e;
622+
List<org.jvnet.hudson.reactor.Handle> reqs = new ArrayList<>();
623+
org.jvnet.hudson.reactor.Handle loadH = loadHandles.get(p.getShortName());
624+
if (loadH != null) {
625+
reqs.add(loadH);
626+
}
627+
for (PluginWrapper.Dependency dep : p.getDependencies()) {
628+
org.jvnet.hudson.reactor.Handle h = initHandles.get(dep.shortName);
629+
if (h != null) {
630+
reqs.add(h);
620631
}
621-
});
632+
}
633+
634+
org.jvnet.hudson.reactor.Handle handle = g.requires(reqs.toArray(new org.jvnet.hudson.reactor.Handle[0]))
635+
.notFatal()
636+
.attains(PLUGINS_STARTED)
637+
.add("Initializing plugin " + p.getShortName(), reactor -> {
638+
if (!activePlugins.contains(p)) {
639+
return;
640+
}
641+
try {
642+
p.getPluginOrFail().postInitialize();
643+
} catch (Exception e) {
644+
failedPlugins.add(new FailedPlugin(p, e));
645+
activePlugins.remove(p);
646+
plugins.remove(p);
647+
p.releaseClassLoader();
648+
throw e;
649+
}
650+
});
651+
initHandles.put(p.getShortName(), handle);
622652
}
623653

624-
g.followedBy().attains(PLUGINS_STARTED).add("Discovering plugin initialization tasks", reactor -> {
654+
g.requires(initHandles.values().toArray(new org.jvnet.hudson.reactor.Handle[0]))
655+
.attains(PLUGINS_STARTED)
656+
.add("Discovering plugin initialization tasks", reactor -> {
625657
// rescan to find plugin-contributed @Initializer
626658
reactor.addAll(initializerFinder.discoverTasks(reactor));
627659
});

0 commit comments

Comments
 (0)