From 46d94e08802c58ea7a2c5c0c68666d266bc7b6bf Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Tue, 12 Feb 2013 11:29:52 -0500 Subject: [PATCH] Adding a mechanism for NodeProvisioner to know when it's done. This came from pull request #705 --- core/src/main/java/hudson/slaves/Cloud.java | 7 ++-- .../java/hudson/slaves/NodeProvisioner.java | 39 ++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/hudson/slaves/Cloud.java b/core/src/main/java/hudson/slaves/Cloud.java index 5c31798a8f..74fb0e8dbd 100644 --- a/core/src/main/java/hudson/slaves/Cloud.java +++ b/core/src/main/java/hudson/slaves/Cloud.java @@ -106,13 +106,14 @@ public abstract class Cloud extends AbstractModelObject implements ExtensionPoin * Always >= 1. For example, if this is 3, the implementation * should launch 3 slaves with 1 executor each, or 1 slave with * 3 executors, etc. - * * @return * {@link PlannedNode}s that represent asynchronous {@link Node} * 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 - * 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 provision(Label label, int excessWorkload); diff --git a/core/src/main/java/hudson/slaves/NodeProvisioner.java b/core/src/main/java/hudson/slaves/NodeProvisioner.java index c1b028cdb4..4abe5e72d5 100644 --- a/core/src/main/java/hudson/slaves/NodeProvisioner.java +++ b/core/src/main/java/hudson/slaves/NodeProvisioner.java @@ -52,22 +52,56 @@ public class NodeProvisioner { /** * 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 * 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.) */ 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 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; + /** + * 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 future, int numExecutors) { if(displayName==null || future==null || numExecutors<1) throw new IllegalArgumentException(); this.displayName = displayName; this.future = future; this.numExecutors = numExecutors; } + + /** + * Indicate that this {@link PlannedNode} is being finalized. + * + *

+ * {@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. + * + *

+ * 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 { } catch (IOException e) { LOGGER.log(Level.WARNING, "Provisioned slave "+f.displayName+" failed to launch",e); } + + f.spent(); + itr.remove(); } else plannedCapacitySnapshot += f.numExecutors; -- GitLab