Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-30269] Take advantage of TailCall
  • Loading branch information
amuniz committed Mar 15, 2016
1 parent aea4806 commit 59049a5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 19 deletions.
9 changes: 9 additions & 0 deletions pom.xml
Expand Up @@ -85,6 +85,8 @@
<artifactId>annotations</artifactId>
<version>3.0.0</version>
</dependency>

<!-- Testing scope -->
<dependency>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
Expand All @@ -97,6 +99,13 @@
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>${workflow.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
@@ -1,5 +1,6 @@
package org.jenkins.plugins.lockableresources;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -91,7 +92,7 @@ public Void apply(@Nonnull LockStepExecution execution) {
});
}

private static final class Callback extends BodyExecutionCallback {
private static final class Callback extends BodyExecutionCallback.TailCall {

private final LockableResourcesStruct resourceHolder;
private transient Run<?, ?> run;
Expand All @@ -104,30 +105,18 @@ private static final class Callback extends BodyExecutionCallback {
this.buildExternalizableId = run.getExternalizableId();
}

@Override
public void onSuccess(StepContext context, Object result) {
protected void finished(StepContext context) throws Exception {
unlock(context);
context.onSuccess(result);
}

@Override
public void onFailure(StepContext context, Throwable t) {
unlock(context);
context.onFailure(t);
}

private void unlock(StepContext context) {
private void unlock(StepContext context) throws IOException, InterruptedException {
if (run == null && buildExternalizableId != null) {
run = Run.fromExternalizableId(buildExternalizableId);
}
LockableResourcesManager.get().unlock(resourceHolder.required, run);
try {
// It's granted to contain one (and only one for now)
context.get(TaskListener.class).getLogger().println("Lock released on resouce [" + resourceHolder.required.get(0) + "]");
LOGGER.finest("Lock released on [" + resourceHolder.required.get(0) + "]");
} catch (Exception e) {
context.onFailure(e);
}
// It's granted to contain one (and only one for now)
context.get(TaskListener.class).getLogger().println("Lock released on resouce [" + resourceHolder.required.get(0) + "]");
LOGGER.finest("Lock released on [" + resourceHolder.required.get(0) + "]");
}

private static final long serialVersionUID = 1L;
Expand Down
Expand Up @@ -4,7 +4,9 @@
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.RestartableJenkinsRule;

Expand All @@ -13,19 +15,37 @@ public class LockStepTest {
@Rule
public RestartableJenkinsRule story = new RestartableJenkinsRule();

@Test
public void lockOrder() {
story.addStep(new Statement() {
@Override
public void evaluate() throws Throwable {
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
"echo 'Start'\n" +
"semaphore 'wait'\n" +
"lock('resource1') {\n" +
" semaphore 'wait'\n" +
" semaphore 'wait-inside'\n" +
"}\n" +
"echo 'Finish'"
));
WorkflowRun b1 = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.success("wait/1", null);
SemaphoreStep.waitForStart("wait-inside/1", b1);

WorkflowRun b2 = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/2", b2);
WorkflowRun b3 = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/3", b3);

// Let's b3 reach the lock before
SemaphoreStep.success("wait/3", null);
SemaphoreStep.success("wait/2", null);

SemaphoreStep.success("wait-inside/1", null);

System.out.println(b3.getLog());
story.j.assertLogContains("acquired", b3);
}
});
}
Expand Down

0 comments on commit 59049a5

Please sign in to comment.