提交 46d94e08 编写于 作者: K Kevin P. Fleming 提交者: Kohsuke Kawaguchi

Adding a mechanism for NodeProvisioner to know when it's done.

This came from pull request #705
上级 4b1a95f2
...@@ -106,13 +106,14 @@ public abstract class Cloud extends AbstractModelObject implements ExtensionPoin ...@@ -106,13 +106,14 @@ public abstract class Cloud extends AbstractModelObject implements ExtensionPoin
* Always >= 1. For example, if this is 3, the implementation * Always >= 1. For example, if this is 3, the implementation
* should launch 3 slaves with 1 executor each, or 1 slave with * should launch 3 slaves with 1 executor each, or 1 slave with
* 3 executors, etc. * 3 executors, etc.
*
* @return * @return
* {@link PlannedNode}s that represent asynchronous {@link Node} * {@link PlannedNode}s that represent asynchronous {@link Node}
* provisioning operations. Can be empty but must not be null. * provisioning operations. Can be empty but must not be null.
* {@link NodeProvisioner} will be responsible for adding the resulting {@link Node} * {@link NodeProvisioner} will be responsible for adding the resulting {@link Node}s
* into Hudson via {@link jenkins.model.Jenkins#addNode(Node)}, so a {@link Cloud} implementation * into Hudson via {@link jenkins.model.Jenkins#addNode(Node)}, so a {@link Cloud} implementation
* just needs to create a new node object. * just needs to return {@link PlannedNode}s that each contain an object that implements {@link Future}.
* When the {@link Future} has completed its work, {@link Future#get} will be called to obtain the
* provisioned {@link Node} object.
*/ */
public abstract Collection<PlannedNode> provision(Label label, int excessWorkload); public abstract Collection<PlannedNode> provision(Label label, int excessWorkload);
......
...@@ -52,22 +52,56 @@ public class NodeProvisioner { ...@@ -52,22 +52,56 @@ public class NodeProvisioner {
/** /**
* The node addition activity in progress. * The node addition activity in progress.
*/ */
public static final class PlannedNode { public static class PlannedNode {
/** /**
* Used to display this planned node to UI. Should ideally include the identifier unique to the node * Used to display this planned node to UI. Should ideally include the identifier unique to the node
* being provisioned (like the instance ID), but if such an identifier doesn't readily exist, this * being provisioned (like the instance ID), but if such an identifier doesn't readily exist, this
* can be just a name of the template being provisioned (like the machine image ID.) * can be just a name of the template being provisioned (like the machine image ID.)
*/ */
public final String displayName; public final String displayName;
/**
* Used to launch and return a {@link Node} object. {@link NodeProvisioner} will check
* this {@link Future}'s isDone() method to determine when to finalize this object.
*/
public final Future<Node> future; public final Future<Node> future;
/**
* The number of executors that will be provided by the {@link Node} launched by
* this object. This is used for capacity planning in {@link NodeProvisioner#update}.
*/
public final int numExecutors; public final int numExecutors;
/**
* Construct a PlannedNode instance without {@link Cloud} callback for finalization.
*
* @param displayName Used to display this object in the UI.
* @param future Used to launch a @{link Node} object.
* @param numExecutors The number of executors that will be provided by the launched {@link Node}.
*/
public PlannedNode(String displayName, Future<Node> future, int numExecutors) { public PlannedNode(String displayName, Future<Node> future, int numExecutors) {
if(displayName==null || future==null || numExecutors<1) throw new IllegalArgumentException(); if(displayName==null || future==null || numExecutors<1) throw new IllegalArgumentException();
this.displayName = displayName; this.displayName = displayName;
this.future = future; this.future = future;
this.numExecutors = numExecutors; this.numExecutors = numExecutors;
} }
/**
* Indicate that this {@link PlannedNode} is being finalized.
*
* <p>
* {@link NodeProvisioner} will call this method when it's done with {@link PlannedNode}.
* This indicates that the {@link PlannedNode}'s work has been completed
* (successfully or otherwise) and it is about to be removed from the list of pending
* {@link Node}s to be launched.
*
* <p>
* Create a subtype of this class and override this method to add any necessary behaviour.
*
* @since 1.503
*/
public void spent() {
}
} }
/** /**
...@@ -152,6 +186,9 @@ public class NodeProvisioner { ...@@ -152,6 +186,9 @@ public class NodeProvisioner {
} catch (IOException e) { } catch (IOException e) {
LOGGER.log(Level.WARNING, "Provisioned slave "+f.displayName+" failed to launch",e); LOGGER.log(Level.WARNING, "Provisioned slave "+f.displayName+" failed to launch",e);
} }
f.spent();
itr.remove(); itr.remove();
} else } else
plannedCapacitySnapshot += f.numExecutors; plannedCapacitySnapshot += f.numExecutors;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册