Skip to content

Commit

Permalink
[FIXED JENKINS-22941] AsynchronousExecution.blocksRestart
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Mar 24, 2015
1 parent d073f79 commit 8589b21
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
8 changes: 8 additions & 0 deletions core/src/main/java/hudson/model/Executor.java
Expand Up @@ -413,6 +413,14 @@ public boolean isActive() {
return !started || asynchronousExecution != null || isAlive();
}

/**
* If currently running in asynchronous mode, returns that handle.
* @since TODO
*/
public @CheckForNull AsynchronousExecution getAsynchronousExecution() {
return asynchronousExecution;
}

/**
* Returns true if this executor is waiting for a task to execute.
*/
Expand Down
30 changes: 29 additions & 1 deletion core/src/main/java/hudson/model/RestartListener.java
Expand Up @@ -6,6 +6,7 @@
import jenkins.model.Jenkins;

import java.io.IOException;
import jenkins.model.queue.AsynchronousExecution;

/**
* Extension point that allows plugins to veto the restart.
Expand Down Expand Up @@ -46,12 +47,39 @@ public static boolean isAllReady() throws IOException, InterruptedException {

/**
* Default logic. Wait for all the executors to become idle.
* @see AsynchronousExecution#blocksRestart
*/
@Extension
public static class Default extends RestartListener {
@Override
public boolean isReadyToRestart() throws IOException, InterruptedException {
return new ComputerSet().getBusyExecutors() == 0;
for (Computer c : Jenkins.getInstance().getComputers()) {
if (c.isOnline()) {
for (Executor e : c.getExecutors()) {
if (blocksRestart(e)) {
return false;
}
}
for (Executor e : c.getOneOffExecutors()) {
if (blocksRestart(e)) {
return false;
}
}
}
}
return true;
}
private static boolean blocksRestart(Executor e) {
if (e.isBusy()) {
AsynchronousExecution execution = e.getAsynchronousExecution();
if (execution != null) {
return execution.blocksRestart();
} else {
return true;
}
} else {
return false;
}
}
}
}
8 changes: 2 additions & 6 deletions core/src/main/java/jenkins/model/Jenkins.java
Expand Up @@ -252,7 +252,6 @@
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
Expand Down Expand Up @@ -3492,16 +3491,13 @@ public void run() {
LOGGER.severe(String.format("Shutting down VM as requested by %s from %s",
exitUser, exitAddr));
// Wait 'til we have no active executors.
while (isQuietingDown
&& (overallLoad.computeTotalExecutors() > overallLoad.computeIdleExecutors())) {
Thread.sleep(5000);
}
doQuietDown(true, 0);
// Make sure isQuietingDown is still true.
if (isQuietingDown) {
cleanUp();
System.exit(0);
}
} catch (InterruptedException e) {
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to shutdown Hudson",e);
}
}
Expand Down
Expand Up @@ -65,6 +65,15 @@ protected AsynchronousExecution() {}
*/
public abstract void interrupt(boolean forShutdown);

/**
* Allows an executable to indicate whether it is currently doing something which should prevent Jenkins from being shut down safely.
* You may return false if it is fine for an administrator to exit/restart Jenkins despite this executable still being running.
* (If so, {@link #interrupt} will be passed {@code forShutdown=true}.)
* @return traditionally always true
* @see hudson.model.RestartListener.Default#isReadyToRestart
*/
public abstract boolean blocksRestart();

/**
* Obtains the associated executor.
*/
Expand Down

0 comments on commit 8589b21

Please sign in to comment.