Package hudson.model

Source Code of hudson.model.AbstractCIBase

/*
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Erik Ramfelt, Koichi Fujikawa, Red Hat, Inc., Seiji Sogabe,
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package hudson.model;


import hudson.security.AccessControlled;
import hudson.slaves.ComputerListener;
import hudson.slaves.RetentionStrategy;
import org.kohsuke.stapler.StaplerFallback;
import org.kohsuke.stapler.StaplerProxy;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Logger;

import jenkins.model.Configuration;

public abstract class AbstractCIBase extends Node implements ItemGroup<TopLevelItem>, StaplerProxy, StaplerFallback, ViewGroup, AccessControlled, DescriptorByNameOwner {
   
    public static boolean LOG_STARTUP_PERFORMANCE = Configuration.getBooleanConfigParameter("logStartupPerformance", false);
   
    private static final Logger LOGGER = Logger.getLogger(AbstractCIBase.class.getName());

    private final transient Object updateComputerLock = new Object();

    /**
     * If you are calling this on Hudson something is wrong.
     *
     * @deprecated
     */
    @Deprecated @Override
    public String getNodeName() {
        return "";
    }

   /**
     * @deprecated
     *      Why are you calling a method that always returns ""?
     */
    public String getUrl() {
        return "";
    }

    /* =================================================================================================================
     * Support functions that can only be accessed through package-protected
     * ============================================================================================================== */
    protected void resetLabel(Label l) {
        l.reset();
    }

    protected void setViewOwner(View v) {
        v.owner = this;
    }
    protected void interruptReloadThread() {
        ExternalJob.reloadThread.interrupt();
    }

    protected void killComputer(Computer c) {
        c.kill();
    }

    /* =================================================================================================================
    * Package-protected, but accessed API
    * ============================================================================================================== */

    /*package*/ final CopyOnWriteArraySet<String> disabledAdministrativeMonitors = new CopyOnWriteArraySet<String>();

    /* =================================================================================================================
     * Implementation provided
     * ============================================================================================================== */

     /**
     * Returns all {@link Node}s in the system, excluding {@link jenkins.model.Jenkins} instance itself which
     * represents the master.
     */
    public abstract List<Node> getNodes();

    public abstract Queue getQueue();

    protected abstract Map<Node,Computer> getComputerMap();

    /* =================================================================================================================
     * Computer API uses package protection heavily
     * ============================================================================================================== */

    private void updateComputer(Node n, Map<String,Computer> byNameMap, Set<Computer> used, boolean automaticSlaveLaunch) {
        Map<Node,Computer> computers = getComputerMap();
        Computer c;
        c = byNameMap.get(n.getNodeName());
        if (c!=null) {
            c.setNode(n); // reuse
        } else {
            if(n.getNumExecutors()>0) {
                computers.put(n, c = n.createComputer());
                if (!n.isHoldOffLaunchUntilSave() && automaticSlaveLaunch) {
                    RetentionStrategy retentionStrategy = c.getRetentionStrategy();
                    if (retentionStrategy != null) {
                        // if there is a retention strategy, it is responsible for deciding to start the computer
                        retentionStrategy.start(c);
                    } else {
                        // we should never get here, but just in case, we'll fall back to the legacy behaviour
                        c.connect(true);
                    }
                }
            }
        }
        used.add(c);
    }

    /*package*/ void removeComputer(Computer computer) {
        Map<Node,Computer> computers = getComputerMap();
        for (Map.Entry<Node, Computer> e : computers.entrySet()) {
            if (e.getValue() == computer) {
                computers.remove(e.getKey());
                return;
            }
        }
        throw new IllegalStateException("Trying to remove unknown computer");
    }

    /*package*/ Computer getComputer(Node n) {
        Map<Node,Computer> computers = getComputerMap();
        return computers.get(n);
    }

    /**
     * Updates Computers.
     *
     * <p>
     * This method tries to reuse existing {@link Computer} objects
     * so that we won't upset {@link Executor}s running in it.
     */
    protected void updateComputerList(boolean automaticSlaveLaunch) throws IOException {
        Map<Node,Computer> computers = getComputerMap();
        synchronized(updateComputerLock) {// just so that we don't have two code updating computer list at the same time
            Map<String,Computer> byName = new HashMap<String,Computer>();
            for (Computer c : computers.values()) {
                if(c.getNode()==null)
                    continue;   // this computer is gone
                byName.put(c.getNode().getNodeName(),c);
            }

            Set<Computer> old = new HashSet<Computer>(computers.values());
            Set<Computer> used = new HashSet<Computer>();

            updateComputer(this, byName, used, automaticSlaveLaunch);
            for (Node s : getNodes()) {
                long start = System.currentTimeMillis();
                updateComputer(s, byName, used, automaticSlaveLaunch);
                if(LOG_STARTUP_PERFORMANCE)
                    LOGGER.info(String.format("Took %dms to update node %s",
                            System.currentTimeMillis()-start, s.getNodeName()));
            }

            // find out what computers are removed, and kill off all executors.
            // when all executors exit, it will be removed from the computers map.
            // so don't remove too quickly
            old.removeAll(used);
            for (Computer c : old) {
                killComputer(c);
            }
        }
        getQueue().scheduleMaintenance();
        for (ComputerListener cl : ComputerListener.all())
            cl.onConfigurationChange();
    }

}
TOP

Related Classes of hudson.model.AbstractCIBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.