Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
[FIXED JENKINS-25890] isReady should not block, so getProgramPromise …
Browse files Browse the repository at this point in the history
…may not block on getFlowExecution.
  • Loading branch information
jglick committed Mar 2, 2015
1 parent 8fe11e0 commit 790a545
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -5,6 +5,7 @@ Only noting significant user-visible or major API changes, not internal code cle
## 1.3 (upcoming)

### User changes
* JENKINS-25890: deadlock during restart.
* Fixed some file handle leaks caught by tests which may have affected Windows masters.
* JENKINS-25779: snippet generator now omits default values of complex steps.
* Ability to configure project display name.
Expand Down
Expand Up @@ -650,7 +650,6 @@ public static void finish(final boolean terminate) {
});
}

@RandomlyFails("TODO JENKINS-25890 sometimes triggers a deadlock after restart")
@Issue("JENKINS-26513")
@Test public void executorStepRestart() {
story.addStep(new Statement() {
Expand Down
Expand Up @@ -74,7 +74,7 @@ public void setResult(Result r) {
}

@Override
public boolean isReady() throws IOException, InterruptedException {
public boolean isReady() {
return base.isReady();
}

Expand Down
Expand Up @@ -59,6 +59,7 @@
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.util.Timer;
import org.codehaus.groovy.runtime.InvokerInvocationException;

import static org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext.*;
Expand Down Expand Up @@ -215,7 +216,7 @@ public String getDisplayName() {
*
* This can block for the entire duration of the PREPARING state.
*/
@CheckForNull CpsThread getThreadSynchronously() throws InterruptedException, IOException {
private @CheckForNull CpsThread getThreadSynchronously() throws InterruptedException, IOException {
try {
CpsThreadGroup g = getProgramPromise().get();
return getThread(g);
Expand All @@ -224,13 +225,24 @@ public String getDisplayName() {
}
}

private @Nonnull ListenableFuture<CpsThreadGroup> getProgramPromise() throws IOException {
ListenableFuture<CpsThreadGroup> pp = getFlowExecution().programPromise;
assert pp != null;
return pp;
private @Nonnull ListenableFuture<CpsThreadGroup> getProgramPromise() {
final SettableFuture<CpsThreadGroup> f = SettableFuture.create();
// TODO is there some more convenient way of writing this using Futures.transform?
Timer.get().submit(new Runnable() {
@Override public void run() {
try {
ListenableFuture<CpsThreadGroup> pp = getFlowExecution().programPromise;
assert pp != null;
f.set(pp.get());
} catch (Exception x) { // from getFlowExecution() or get()
f.setException(x);
}
}
});
return f;
}

@Override public boolean isReady() throws IOException, InterruptedException {
@Override public boolean isReady() {
return getProgramPromise().isDone();
}

Expand Down
Expand Up @@ -83,7 +83,7 @@ public abstract class StepContext implements FutureCallback<Object>, Serializabl
* May be called to break deadlocks during reloading.
* @return true normally, false if we are still reloading the context, for example during unpickling
*/
public abstract boolean isReady() throws IOException, InterruptedException;
public abstract boolean isReady();

/**
* Requests that any state held by the {@link StepExecution} be saved to disk.
Expand Down

0 comments on commit 790a545

Please sign in to comment.