Executor.java 3.7 KB
Newer Older
K
kohsuke 已提交
1 2
package hudson.model;

K
kohsuke 已提交
3
import hudson.Util;
K
kohsuke 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import java.io.IOException;


/**
 * Thread that executes builds.
 *
 * @author Kohsuke Kawaguchi
 */
public class Executor extends Thread {
    private final Computer owner;
    private final Queue queue;

20
    private Queue.Task task;
K
kohsuke 已提交
21 22 23

    private long startTime;

K
kohsuke 已提交
24 25 26 27 28
    /**
     * Executor number that identifies it among other executors for the same {@link Computer}.
     */
    private int number;

K
kohsuke 已提交
29 30 31 32
    public Executor(Computer owner) {
        super("Executor #"+owner.getExecutors().size()+" for "+owner.getDisplayName());
        this.owner = owner;
        this.queue = Hudson.getInstance().getQueue();
K
kohsuke 已提交
33
        this.number = owner.getExecutors().size();
K
kohsuke 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
        start();
    }

    public void run() {
        while(true) {
            if(Hudson.getInstance().isTerminating())
                return;

            synchronized(owner) {
                if(owner.getNumExecutors()<owner.getExecutors().size()) {
                    // we've got too many executors.
                    owner.removeExecutor(this);
                    return;
                }
            }

            try {
51
                task = queue.pop();
K
kohsuke 已提交
52 53 54
            } catch (InterruptedException e) {
                continue;
            }
55

K
kohsuke 已提交
56
            try {
57 58
                startTime = System.currentTimeMillis();
                task.execute();
K
kohsuke 已提交
59 60 61 62 63 64
            } catch (Throwable e) {
                // for some reason the executor died. this is really
                // a bug in the code, but we don't want the executor to die,
                // so just leave some info and go on to build other things
                e.printStackTrace();
            }
65
            task = null;
K
kohsuke 已提交
66 67 68 69
        }
    }

    /**
70
     * Returns the current {@link Queue.Task} this executor is running.
K
kohsuke 已提交
71 72 73 74
     *
     * @return
     *      null if the executor is idle.
     */
75 76
    public Queue.Task getCurrentTask() {
        return task;
K
kohsuke 已提交
77 78
    }

K
kohsuke 已提交
79 80 81 82 83 84 85 86 87 88 89
    /**
     * Gets the executor number that uniquely identifies it among
     * other {@link Executor}s for the same computer.
     *
     * @return
     *      a sequential number starting from 0.
     */
    public int getNumber() {
        return number;
    }

K
kohsuke 已提交
90 91 92 93
    /**
     * Returns true if this {@link Executor} is ready for action.
     */
    public boolean isIdle() {
94
        return task==null;
K
kohsuke 已提交
95 96 97 98 99 100 101 102 103
    }

    /**
     * Returns the progress of the current build in the number between 0-100.
     *
     * @return -1
     *      if it's impossible to estimate the progress.
     */
    public int getProgress() {
104 105
        long d = task.getEstimatedDuration();
        if(d<0)         return -1;
K
kohsuke 已提交
106

107
        int num = (int)((System.currentTimeMillis()-startTime)*100/d);
K
kohsuke 已提交
108 109 110 111
        if(num>=100)    num=99;
        return num;
    }

K
kohsuke 已提交
112 113 114 115 116
    /**
     * Computes a human-readable text that shows the expected remaining time
     * until the build completes.
     */
    public String getEstimatedRemainingTime() {
117 118
        long d = task.getEstimatedDuration();
        if(d<0)         return "N/A";
K
kohsuke 已提交
119

120
        long eta = d-(System.currentTimeMillis()-startTime);
K
kohsuke 已提交
121 122 123 124 125
        if(eta<=0)      return "N/A";

        return Util.getTimeSpanString(eta);
    }

K
kohsuke 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    /**
     * Stops the current build.
     */
    public void doStop( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
        if(!Hudson.adminCheck(req,rsp))
            return;

        interrupt();
        rsp.forwardToPreviousPage(req);
    }

    public Computer getOwner() {
        return owner;
    }

    /**
     * Returns the executor of the current thread.
     */
    public static Executor currentExecutor() {
        return (Executor)Thread.currentThread();
    }
}