package hudson.triggers; import antlr.ANTLRException; import hudson.Util; import hudson.model.Action; import hudson.model.Build; import hudson.model.Descriptor; import hudson.model.Project; import hudson.model.TaskListener; import hudson.util.StreamTaskListener; import org.kohsuke.stapler.StaplerRequest; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.Date; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.logging.Level; import java.util.logging.Logger; /** * {@link Trigger} that checks for SCM updates periodically. * * @author Kohsuke Kawaguchi */ public class SCMTrigger extends Trigger { /** * If we'd like to run another polling run, this is set to true. * *
* To avoid submitting more than one polling jobs (which could flood the queue),
* we first use the boolean flag.
*
* @guardedBy this
*/
private transient boolean pollingScheduled;
/**
* Signal to the polling thread to abort now.
*/
private transient boolean abortNow;
/**
* Pending polling activity in progress.
* There's at most one polling activity per project at any given point.
*
* @guardedBy this
*/
private transient Future> polling;
public SCMTrigger(String cronTabSpec) throws ANTLRException {
super(cronTabSpec);
}
protected synchronized void run() {
if(pollingScheduled)
return; // noop
pollingScheduled = true;
// otherwise do it now
startPolling();
}
public Action getProjectAction() {
return new SCMAction();
}
/**
* Makes sure that the polling is aborted.
*/
public synchronized void abort() throws InterruptedException {
if(polling!=null && !polling.isDone()) {
System.out.println("killing polling");
abortNow = true;
polling.cancel(true);
try {
polling.get();
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Failed to poll",e);
} catch (CancellationException e) {
// this is fine
}
abortNow = false;
}
}
/**
* Start polling if it's scheduled.
*/
public synchronized void startPolling() {
Build b = project.getLastBuild();
if(b!=null && b.isBuilding())
return; // build in progress
if(polling!=null && !polling.isDone())
return; // polling already in progress
if(!pollingScheduled)
return; // not scheduled
pollingScheduled = false;
polling = DESCRIPTOR.getExecutor().submit(new Runner());
}
/**
* Returns the file that records the last/current polling activity.
*/
public File getLogFile() {
return new File(project.getRootDir(),"scm-polling.log");
}
public Descriptor