Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,33 @@
public final class WaitForConditionStep extends Step {

static final long MIN_RECURRENCE_PERIOD = 250; // ¼s
static final long MAX_RECURRENCE_PERIOD = 15000; // ¼min
static final long DEFAULT_MAX_RECURRENCE_PERIOD = 15000; // ¼min

private long initialRecurrencePeriod = MIN_RECURRENCE_PERIOD;
private long maxRecurrencePeriod = DEFAULT_MAX_RECURRENCE_PERIOD;
private boolean quiet = false;

@DataBoundConstructor
public WaitForConditionStep() {}

@DataBoundSetter
public void setInitialRecurrencePeriod(long initialRecurrencePeriod) {
this.initialRecurrencePeriod =
Math.max(MIN_RECURRENCE_PERIOD, Math.min(initialRecurrencePeriod, MAX_RECURRENCE_PERIOD));
this.initialRecurrencePeriod = Math.max(MIN_RECURRENCE_PERIOD, initialRecurrencePeriod);
}

public long getInitialRecurrencePeriod() {
return initialRecurrencePeriod;
}

@DataBoundSetter
public void setMaxRecurrencePeriod(long maxRecurrencePeriod) {
this.maxRecurrencePeriod = maxRecurrencePeriod;
}

public long getMaxRecurrencePeriod(long maxRecurrencePeriod) {
return maxRecurrencePeriod;
}

@DataBoundSetter
public void setQuiet(boolean quiet) {
this.quiet = quiet;
Expand All @@ -69,7 +78,11 @@ public boolean getQuiet() {

@Override
public StepExecution start(StepContext context) throws Exception {
return new Execution(context, initialRecurrencePeriod, this.quiet);
if (maxRecurrencePeriod < initialRecurrencePeriod) {
throw new IllegalStateException("The initial recurrance period must not be greater than the maximum.");
}
long initial = Math.max(MIN_RECURRENCE_PERIOD, Math.min(initialRecurrencePeriod, maxRecurrencePeriod));
return new Execution(context, initial, maxRecurrencePeriod, this.quiet);
}

public static final class Execution extends AbstractStepExecutionImpl {
Expand All @@ -85,12 +98,14 @@ public static final class Execution extends AbstractStepExecutionImpl {

private static final float RECURRENCE_PERIOD_BACKOFF = 1.2f;
private long initialRecurrencePeriod;
private long maxRecurrencePeriod;
long recurrencePeriod;
private final boolean quiet;

Execution(StepContext context, long initialRecurrencePeriod, boolean quiet) {
Execution(StepContext context, long initialRecurrencePeriod, long maxRecurrencePeriod, boolean quiet) {
super(context);
this.initialRecurrencePeriod = initialRecurrencePeriod;
this.maxRecurrencePeriod = maxRecurrencePeriod;
recurrencePeriod = initialRecurrencePeriod;
this.quiet = quiet;
}
Expand All @@ -100,6 +115,9 @@ private Object readResolve() {
if (initialRecurrencePeriod == 0) {
initialRecurrencePeriod = MIN_RECURRENCE_PERIOD;
}
if (maxRecurrencePeriod == 0) {
maxRecurrencePeriod = DEFAULT_MAX_RECURRENCE_PERIOD;
}
return this;
}

Expand Down Expand Up @@ -162,7 +180,7 @@ private void retry(StepContext perBodyContext) {
},
recurrencePeriod,
TimeUnit.MILLISECONDS);
recurrencePeriod = Math.min((long) (recurrencePeriod * RECURRENCE_PERIOD_BACKOFF), MAX_RECURRENCE_PERIOD);
recurrencePeriod = Math.min((long) (recurrencePeriod * RECURRENCE_PERIOD_BACKOFF), maxRecurrencePeriod);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ THE SOFTWARE.
<f:entry field="initialRecurrencePeriod" title="${%Initial Recurrence Period Milliseconds}">
<f:number clazz="positive-number"/>
</f:entry>
<f:entry field="maxRecurrencePeriod" title="${%Maximum Recurrence Period Milliseconds}">
<f:number clazz="positive-number"/>
</f:entry>
<f:entry field="quiet" title="${%Quiet Mode}">
<f:checkbox checked="false"/>
</f:entry>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ void initialRecurrence() throws Throwable {
});
}

@Test
void maxRecurrence() throws Throwable {
sessions.then(j -> {
WorkflowJob p = j.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
"waitUntil(initialRecurrencePeriod: 250, maxRecurrencePeriod: 255) {semaphore 'wait'}; semaphore 'waited'", true));
WorkflowRun b = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/1", b);
SemaphoreStep.success("wait/1", false);
SemaphoreStep.waitForStart("wait/2", b);
SemaphoreStep.success("wait/2", false);
SemaphoreStep.waitForStart("wait/3", b);
SemaphoreStep.success("wait/3", true);
SemaphoreStep.waitForStart("waited/1", b);
SemaphoreStep.success("waited/1", null);
WorkflowRun run = j.assertBuildStatusSuccess(j.waitForCompletion(b));
j.assertLogContains("Will try again after " + Util.getTimeSpanString(250), run);
j.assertLogContains("Will try again after " + Util.getTimeSpanString(255), run);
});
}

@Test
void failure() throws Throwable {
sessions.then(j -> {
Expand Down