diff --git a/core/src/main/java/hudson/model/AbstractCIBase.java b/core/src/main/java/hudson/model/AbstractCIBase.java index cea9a5bf99..f4e2976614 100644 --- a/core/src/main/java/hudson/model/AbstractCIBase.java +++ b/core/src/main/java/hudson/model/AbstractCIBase.java @@ -94,10 +94,6 @@ public abstract class AbstractCIBase extends Node implements ItemGroup disabledAdministrativeMonitors = new HashSet<>(); /** @@ -267,12 +263,12 @@ public abstract class AbstractCIBase extends Node implements ItemGroup - * Note that at this point {@link #getNode()} returns null. - * - *

- * Note that the Queue lock is already held when this method is called. - * - * @see #onRemoved() - */ - @Restricted(NoExternalUse.class) - @GuardedBy("hudson.model.Queue.lock") - /*package*/ void inflictMortalWound() { - setNumExecutors(0); - } - /** * Called by {@link Jenkins} when this computer is removed. * @@ -865,7 +848,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * Calling path, *means protected by Queue.withLock * * Computer.doConfigSubmit -> Computer.replaceBy ->Jenkins.setNodes* ->Computer.setNode - * AbstractCIBase.updateComputerList->Computer.inflictMortalWound* + * AbstractCIBase.updateComputerList->Computer.setNumExecutors* * AbstractCIBase.updateComputerList->AbstractCIBase.updateComputer* ->Computer.setNode * AbstractCIBase.updateComputerList->AbstractCIBase.killComputer->Computer.kill * Computer.constructor->Computer.setNode @@ -873,8 +856,9 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * * @param n number of executors */ + @Restricted(NoExternalUse.class) @GuardedBy("hudson.model.Queue.lock") - private void setNumExecutors(int n) { + public void setNumExecutors(int n) { this.numExecutors = n; final int diff = executors.size() - n; diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index eb25d5906c..c0d5da9885 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -3775,7 +3775,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve for (Computer c : getComputersCollection()) { try { c.interrupt(); - killComputer(c); + c.setNumExecutors(0); pending.add(c.disconnect(null)); } catch (OutOfMemoryError e) { // we should just propagate this, no point trying to log @@ -3950,9 +3950,15 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve if (!pending.isEmpty()) { LOGGER.log(Main.isUnitTest ? Level.FINE : Level.INFO, "Waiting for node disconnection completion"); } + long end = System.nanoTime() + Duration.ofSeconds(10).toNanos(); for (Future f : pending) { try { - f.get(10, TimeUnit.SECONDS); // if clean up operation didn't complete in time, we fail the test + long remaining = end - System.nanoTime(); + if (remaining <= 0) { + LOGGER.warning("Ran out of time waiting for agents to disconnect"); + break; + } + f.get(remaining, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; // someone wants us to die now. quick!