Search in sources :

Example 1 with TaskBuilder

use of org.jvnet.hudson.reactor.TaskBuilder in project hudson-2.x by hudson.

the class PluginManager method initTasks.

/**
     * Called immediately after the construction.
     * This is a separate method so that code executed from here will see a valid value in
     * {@link Hudson#pluginManager}. 
     */
public TaskBuilder initTasks(final InitStrategy initStrategy) {
    TaskBuilder builder;
    if (!pluginListed) {
        builder = new TaskGraphBuilder() {

            List<File> archives;

            Collection<String> bundledPlugins;

            {
                Handle loadBundledPlugins = add("Loading bundled plugins", new Executable() {

                    public void run(Reactor session) throws Exception {
                        bundledPlugins = loadBundledPlugins();
                    }
                });
                Handle listUpPlugins = requires(loadBundledPlugins).add("Listing up plugins", new Executable() {

                    public void run(Reactor session) throws Exception {
                        archives = initStrategy.listPluginArchives(PluginManager.this);
                    }
                });
                requires(listUpPlugins).attains(PLUGINS_LISTED).add("Preparing plugins", new Executable() {

                    public void run(Reactor session) throws Exception {
                        // once we've listed plugins, we can fill in the reactor with plugin-specific initialization tasks
                        TaskGraphBuilder g = new TaskGraphBuilder();
                        final Map<String, File> inspectedShortNames = new HashMap<String, File>();
                        for (final File arc : archives) {
                            g.followedBy().notFatal().attains(PLUGINS_LISTED).add("Inspecting plugin " + arc, new Executable() {

                                public void run(Reactor session1) throws Exception {
                                    try {
                                        PluginWrapper p = strategy.createPluginWrapper(arc);
                                        if (isDuplicate(p))
                                            return;
                                        p.isBundled = bundledPlugins.contains(arc.getName());
                                        plugins.add(p);
                                        if (p.isActive())
                                            activePlugins.add(p);
                                    } catch (IOException e) {
                                        failedPlugins.add(new FailedPlugin(arc.getName(), e));
                                        throw e;
                                    }
                                }

                                /**
                                     * Inspects duplication. this happens when you run hpi:run on a bundled plugin,
                                     * as well as putting numbered hpi files, like "cobertura-1.0.hpi" and "cobertura-1.1.hpi"
                                     */
                                private boolean isDuplicate(PluginWrapper p) {
                                    String shortName = p.getShortName();
                                    if (inspectedShortNames.containsKey(shortName)) {
                                        LOGGER.info("Ignoring " + arc + " because " + inspectedShortNames.get(shortName) + " is already loaded");
                                        return true;
                                    }
                                    inspectedShortNames.put(shortName, arc);
                                    return false;
                                }
                            });
                        }
                        g.requires(PLUGINS_PREPARED).add("Checking cyclic dependencies", new Executable() {

                            /**
                                 * Makes sure there's no cycle in dependencies.
                                 */
                            public void run(Reactor reactor) throws Exception {
                                try {
                                    new CyclicGraphDetector<PluginWrapper>() {

                                        @Override
                                        protected List<PluginWrapper> getEdges(PluginWrapper p) {
                                            List<PluginWrapper> next = new ArrayList<PluginWrapper>();
                                            addTo(p.getDependencies(), next);
                                            addTo(p.getOptionalDependencies(), next);
                                            return next;
                                        }

                                        private void addTo(List<Dependency> dependencies, List<PluginWrapper> r) {
                                            for (Dependency d : dependencies) {
                                                PluginWrapper p = getPlugin(d.shortName);
                                                if (p != null)
                                                    r.add(p);
                                            }
                                        }
                                    }.run(getPlugins());
                                } catch (CycleDetectedException e) {
                                    // disable all plugins since classloading from them can lead to StackOverflow
                                    stop();
                                    // let Hudson fail
                                    throw e;
                                }
                                Collections.sort(plugins);
                            }
                        });
                        session.addAll(g.discoverTasks(session));
                        // technically speaking this is still too early, as at this point tasks are merely scheduled, not necessarily executed.
                        pluginListed = true;
                    }
                });
            }
        };
    } else {
        builder = TaskBuilder.EMPTY_BUILDER;
    }
    // misc. stuff
    final InitializerFinder initializerFinder = new InitializerFinder(uberClassLoader);
    // lists up initialization tasks about loading plugins.
    return // this scans @Initializer in the core once
    TaskBuilder.union(// this scans @Initializer in the core once
    initializerFinder, builder, new TaskGraphBuilder() {

        {
            requires(PLUGINS_LISTED).attains(PLUGINS_PREPARED).add("Loading plugins", new Executable() {

                /**
                 * Once the plugins are listed, schedule their initialization.
                 */
                public void run(Reactor session) throws Exception {
                    Hudson.getInstance().lookup.set(PluginInstanceStore.class, new PluginInstanceStore());
                    TaskGraphBuilder g = new TaskGraphBuilder();
                    // schedule execution of loading plugins
                    for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) {
                        g.followedBy().notFatal().attains(PLUGINS_PREPARED).add("Loading plugin " + p.getShortName(), new Executable() {

                            public void run(Reactor session) throws Exception {
                                try {
                                    p.resolvePluginDependencies();
                                    strategy.load(p);
                                } catch (IOException e) {
                                    failedPlugins.add(new FailedPlugin(p.getShortName(), e));
                                    activePlugins.remove(p);
                                    plugins.remove(p);
                                    throw e;
                                }
                            }
                        });
                    }
                    // schedule execution of initializing plugins
                    for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) {
                        g.followedBy().notFatal().attains(PLUGINS_STARTED).add("Initializing plugin " + p.getShortName(), new Executable() {

                            public void run(Reactor session) throws Exception {
                                try {
                                    p.getPlugin().postInitialize();
                                } catch (Exception e) {
                                    failedPlugins.add(new FailedPlugin(p.getShortName(), e));
                                    activePlugins.remove(p);
                                    plugins.remove(p);
                                    throw e;
                                }
                            }
                        });
                    }
                    g.followedBy().attains(PLUGINS_STARTED).add("Discovering plugin initialization tasks", new Executable() {

                        public void run(Reactor reactor) throws Exception {
                            // rescan to find plugin-contributed @Initializer
                            reactor.addAll(initializerFinder.discoverTasks(reactor));
                        }
                    });
                    // register them all
                    session.addAll(g.discoverTasks(session));
                }
            });
        }
    });
}
Also used : TaskBuilder(org.jvnet.hudson.reactor.TaskBuilder) InitializerFinder(hudson.init.InitializerFinder) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CycleDetectedException(hudson.util.CyclicGraphDetector.CycleDetectedException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Dependency(hudson.PluginWrapper.Dependency) ServletException(javax.servlet.ServletException) CycleDetectedException(hudson.util.CyclicGraphDetector.CycleDetectedException) IOException(java.io.IOException) TaskGraphBuilder(org.jvnet.hudson.reactor.TaskGraphBuilder) List(java.util.List) PersistedList(hudson.util.PersistedList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Executable(org.jvnet.hudson.reactor.Executable) Reactor(org.jvnet.hudson.reactor.Reactor) CyclicGraphDetector(hudson.util.CyclicGraphDetector) File(java.io.File)

Aggregations

Dependency (hudson.PluginWrapper.Dependency)1 InitializerFinder (hudson.init.InitializerFinder)1 CyclicGraphDetector (hudson.util.CyclicGraphDetector)1 CycleDetectedException (hudson.util.CyclicGraphDetector.CycleDetectedException)1 PersistedList (hudson.util.PersistedList)1 File (java.io.File)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 ServletException (javax.servlet.ServletException)1 Executable (org.jvnet.hudson.reactor.Executable)1 Reactor (org.jvnet.hudson.reactor.Reactor)1 TaskBuilder (org.jvnet.hudson.reactor.TaskBuilder)1 TaskGraphBuilder (org.jvnet.hudson.reactor.TaskGraphBuilder)1