Skip to content
Permalink
Browse files

Merge pull request #91 from jglick/ISE-JENKINS-42511

[JENKINS-42511] Race condition in PeriodicFolderTrigger
  • Loading branch information
stephenc committed Mar 8, 2017
2 parents 0d35973 + 7ee310e commit 93690dbd078a4a8db63e36b1e65a8fa2b0f1219e
@@ -550,6 +550,7 @@ public long getEstimatedDuration() {
public final FolderComputation<I> createExecutable() throws IOException {
FolderComputation<I> c = createComputation(computation);
computation = c;
LOGGER.log(Level.FINE, "Recording {0} @{1}", new Object[] {c, c.getTimestamp()});
return c;
}

@@ -25,13 +25,16 @@

import antlr.ANTLRException;
import hudson.Extension;
import hudson.model.Cause;
import hudson.model.Item;
import hudson.model.Items;
import hudson.triggers.TimerTrigger;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import hudson.util.ListBoxModel;
import hudson.util.TimeUnit2;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;

@@ -43,11 +46,20 @@
*/
public class PeriodicFolderTrigger extends Trigger<ComputedFolder<?>> {

private static final Logger LOGGER = Logger.getLogger(PeriodicFolderTrigger.class.getName());

/**
* The interval between successive indexings.
*/
private final long interval;

/**
* Timestamp when we last {@link #run}.
* Normally we rely on {@link FolderComputation#getTimestamp} but there is a slight delay
* between {@link ComputedFolder#scheduleBuild(int, Cause)} and {@link ComputedFolder#createExecutable}.
*/
private transient long lastTriggered; // could be volatile or AtomicLong, but FolderCron will not run >1 concurrently anyway

/**
* Constructor.
*
@@ -159,14 +171,24 @@ public String getInterval() {
*/
@Override
public void run() {
long now = System.currentTimeMillis();
FolderComputation<?> computation = job.getComputation();
if (computation != null) {
long delay = System.currentTimeMillis() - computation.getTimestamp().getTimeInMillis();
long delay = now - computation.getTimestamp().getTimeInMillis();
if (delay < interval) {
LOGGER.log(Level.FINE, "Too early to reschedule {0} based on last computation", job);
return;
}
}
job.scheduleBuild(0, new TimerTrigger.TimerTriggerCause());
if (now - lastTriggered < interval) {
LOGGER.log(Level.FINE, "Too early to reschedule {0} based on last triggering", job);
return;
}
if (job.scheduleBuild(0, new TimerTrigger.TimerTriggerCause())) {
lastTriggered = now;
} else {
LOGGER.log(Level.WARNING, "Queue refused to schedule {0}", job);
}
}

/**

0 comments on commit 93690db

Please sign in to comment.
You can’t perform that action at this time.