提交 375cca85 编写于 作者: K kohsuke

Creating a package to host slave related code.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@9393 71c3de6d-444a-0410-be80-ed276b4c234a
上级 295650c0
......@@ -13,6 +13,8 @@ import hudson.security.SecurityRealm;
import hudson.security.AuthorizationStrategy;
import hudson.security.Permission;
import hudson.util.Area;
import hudson.slaves.SlaveStartMethod;
import hudson.slaves.SlaveAvailabilityStrategy;
import org.apache.commons.jexl.parser.ASTSizeFunction;
import org.apache.commons.jexl.util.Introspector;
import org.apache.commons.jelly.JellyContext;
......@@ -48,7 +50,6 @@ import java.util.TreeMap;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Utility functions used in views.
......
package hudson.model;
import hudson.EnvVars;
import hudson.slaves.SlaveStartMethod;
import hudson.node_monitors.NodeMonitor;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
......@@ -125,7 +126,7 @@ public abstract class Computer extends AbstractModelObject {
/**
* Returns true if this computer is supposed to be launched via JNLP.
* @deprecated see {@linkplain #isLaunchSupported()} and {@linkplain hudson.model.SlaveStartMethod}
* @deprecated see {@linkplain #isLaunchSupported()} and {@linkplain SlaveStartMethod}
*/
@Exported
@Deprecated
......
......@@ -14,6 +14,8 @@ import hudson.TcpSlaveAgentListener;
import hudson.Util;
import static hudson.Util.fixEmpty;
import hudson.XmlFile;
import hudson.slaves.SlaveStartMethod;
import hudson.slaves.SlaveAvailabilityStrategy;
import hudson.model.Descriptor.FormException;
import hudson.model.listeners.ItemListener;
import hudson.model.listeners.JobListener;
......
......@@ -5,6 +5,8 @@ import hudson.FilePath;
import hudson.Launcher;
import hudson.Launcher.RemoteLauncher;
import hudson.Util;
import hudson.slaves.SlaveStartMethod;
import hudson.slaves.SlaveAvailabilityStrategy;
import hudson.maven.agent.Main;
import hudson.maven.agent.PluginManagerInterceptor;
import hudson.model.Descriptor.FormException;
......
package hudson.slaves;
import hudson.util.DescriptorList;
import hudson.ExtensionPoint;
import hudson.model.Describable;
import hudson.model.Slave;
import hudson.model.Descriptor;
import org.kohsuke.stapler.StaplerRequest;
import net.sf.json.JSONObject;
/**
* Slave availability strategy
*/
public abstract class SlaveAvailabilityStrategy implements Describable<SlaveAvailabilityStrategy>, ExtensionPoint {
/**
* This method will be called periodically to allow this strategy to decide what to do with it's owning slave.
* The default implementation takes the slave on-line every time it's off-line.
*
* @param slave The slave that owns this strategy, i.e. {@code slave.getAvailabilityStrategy() == this}
* @param state Some state information that may be useful in deciding what to do.
* @return The number of minutes after which the strategy would like to be checked again. The strategy may be
* rechecked earlier or later that this!
*/
public long check(Slave slave, State state) {
Slave.ComputerImpl c = slave.getComputer();
if (c != null && c.isOffline() && c.isLaunchSupported())
c.tryReconnect();
return 5;
}
/**
* All registered {@link SlaveAvailabilityStrategy} implementations.
*/
public static final DescriptorList<SlaveAvailabilityStrategy> LIST = new DescriptorList<SlaveAvailabilityStrategy>(
Always.DESCRIPTOR
);
public static class State {
private final boolean jobWaiting;
private final boolean jobRunning;
public State(boolean jobWaiting, boolean jobRunning) {
this.jobWaiting = jobWaiting;
this.jobRunning = jobRunning;
}
public boolean isJobWaiting() {
return jobWaiting;
}
public boolean isJobRunning() {
return jobRunning;
}
}
public static class Always extends SlaveAvailabilityStrategy {
public Descriptor<SlaveAvailabilityStrategy> getDescriptor() {
return DESCRIPTOR;
}
public static final Descriptor<SlaveAvailabilityStrategy> DESCRIPTOR =
new DescriptorImpl();
private static class DescriptorImpl extends Descriptor<SlaveAvailabilityStrategy> {
public DescriptorImpl() {
super(Always.class);
}
public String getDisplayName() {
return "Keep this slave on-line as much as possible";
}
public SlaveAvailabilityStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new Always();
}
}
}
}
package hudson.slaves;
import hudson.model.Slave;
import hudson.model.Hudson;
import hudson.model.Queue;
import hudson.model.Executor;
import hudson.triggers.SafeTimerTask;
import java.util.Map;
import java.util.WeakHashMap;
/**
* Periodically checks the slaves and try to reconnect dead slaves.
*
* @author Kohsuke Kawaguchi
*/
public class SlaveReconnectionWork extends SafeTimerTask {
protected void doRun() {
// use a weak hashmap
Map<Slave, Long> nextCheck = new WeakHashMap<Slave, Long>();
for (Slave s : Hudson.getInstance().getSlaves()) {
if (!nextCheck.containsKey(s) || System.currentTimeMillis() > nextCheck.get(s)) {
final Queue queue = Hudson.getInstance().getQueue();
boolean hasJob = false;
for (Executor exec: s.getComputer().getExecutors()) {
if (!exec.isIdle()) {
hasJob = true;
break;
}
}
// TODO get only the items from the queue that can apply to this slave
SlaveAvailabilityStrategy.State state = new SlaveAvailabilityStrategy.State(queue.getItems().length > 0, hasJob);
// at the moment I don't trust strategies to wait more than 60 minutes
// strategies need to wait at least one minute
final long waitInMins = Math.min(1, Math.max(60, s.getAvailabilityStrategy().check(s, state)));
nextCheck.put(s, System.currentTimeMillis() + 60 * 1000 * waitInMins);
}
}
}
}
package hudson.slaves;
import hudson.ExtensionPoint;
import hudson.model.Slave.ComputerImpl;
import hudson.model.Describable;
import hudson.model.Computer;
import hudson.remoting.Channel.Listener;
import hudson.util.DescriptorList;
import hudson.util.StreamTaskListener;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Extension point to allow control over how Slaves are started.
*
* @author Stephen Connolly
* @since 24-Apr-2008 22:12:35
*/
public abstract class SlaveStartMethod implements Describable<SlaveStartMethod>, ExtensionPoint {
/**
* Returns true if this {@link SlaveStartMethod} supports
* programatic launch of the slave agent in the target {@link Computer}.
*/
public boolean isLaunchSupported() {
return true;
}
/**
* Launches the slave agent for the given {@link Computer}.
*
* <p>
* If the slave agent is launched successfully, {@link ComputerImpl#setChannel(InputStream, OutputStream, OutputStream, Listener)}
* should be invoked in the end to notify Hudson of the established connection.
* The operation could also fail, in which case there's no need to make any callback notification,
* (except to notify the user of the failure through {@link StreamTaskListener}.)
*
* @param listener
* The progress of the launch, as well as any error, should be sent to this listener.
*/
public abstract void launch(ComputerImpl computer, StreamTaskListener listener);
/**
* All registered {@link SlaveStartMethod} implementations.
*/
public static final DescriptorList<SlaveStartMethod> LIST = new DescriptorList<SlaveStartMethod>();
}
<html>
<body>
Code related to slaves.
</body>
</html>
\ No newline at end of file
......@@ -4,6 +4,7 @@ import antlr.ANTLRException;
import hudson.DependencyRunner;
import hudson.DependencyRunner.ProjectRunnable;
import hudson.ExtensionPoint;
import hudson.slaves.SlaveReconnectionWork;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Build;
......@@ -13,7 +14,6 @@ import hudson.model.FingerprintCleanupThread;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.Project;
import hudson.model.SlaveReconnectionWork;
import hudson.model.WorkspaceCleanupThread;
import hudson.scheduler.CronTab;
import hudson.scheduler.CronTabList;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册