Skip to content
Permalink
Browse files
[FIXES JENKINS-19622] Replace hudson.model.Trigger#timer with jenkins…
….util.Timer, which exposes a ScheduledExecutorService. Up to 10 additional threads will be created to run pending tasks even if running tasks are blocked.

Also, move static initialization of timers to the classes which require them.

(cherry picked from commit 565ced0)

Conflicts:
	core/src/main/java/hudson/model/Queue.java
  • Loading branch information
recampbell authored and olivergondza committed Dec 11, 2013
1 parent 7d602d5 commit 44ee0bb39a134fd12745ccb5e922af93266ad4e2
@@ -24,14 +24,15 @@
package hudson.util

import hudson.model.Computer
import jenkins.util.Timer
import jenkins.model.Jenkins
import hudson.model.Label
import hudson.model.Queue.BlockedItem
import hudson.model.Queue.BuildableItem
import hudson.model.Queue.WaitingItem
import hudson.triggers.SafeTimerTask
import java.text.DateFormat
import hudson.triggers.Trigger;
import java.util.concurrent.TimeUnit

/**
* Spits out the load information.
@@ -51,7 +52,7 @@ public class LoadMonitorImpl extends SafeTimerTask {
this.dataFile = dataFile;
labels = Jenkins.getInstance().labels*.name;
printHeaders();
Trigger.timer.scheduleAtFixedRate(this,0,10*1000);
Timer.get().scheduleAtFixedRate(this,0,10*1000, TimeUnit.MILLISECONDS);
}

private String quote(Object s) { "\"${s}\""; }
@@ -25,14 +25,17 @@

import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.init.Initializer;
import hudson.triggers.SafeTimerTask;
import hudson.triggers.Trigger;
import jenkins.model.Jenkins;
import jenkins.util.Timer;

import java.util.Random;
import java.util.Timer;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import static hudson.init.InitMilestone.JOB_LOADED;


/**
@@ -85,12 +88,17 @@ public long getInitialDelay() {
@Override
public final void doRun() throws Exception{
doAperiodicRun();
Timer timer = Trigger.timer;
if (timer != null) {
timer.schedule(getNewInstance(), getRecurrencePeriod());
Timer.get().schedule(getNewInstance(), getRecurrencePeriod(), TimeUnit.MILLISECONDS);
}

@Initializer(after= JOB_LOADED)
public static void init() {
// start all AperidocWorks
for (AperiodicWork p : AperiodicWork.all()) {
Timer.get().schedule(p, p.getInitialDelay(), TimeUnit.MILLISECONDS);
}
}

protected abstract void doAperiodicRun();

/**
@@ -28,16 +28,19 @@
import hudson.Extension;
import hudson.Util;
import hudson.XmlFile;
import hudson.init.Initializer;
import hudson.model.Descriptor.FormException;
import hudson.model.listeners.SaveableListener;
import hudson.node_monitors.NodeMonitor;
import hudson.slaves.NodeDescriptor;
import hudson.triggers.SafeTimerTask;
import hudson.util.DescribableList;
import hudson.util.FormApply;
import hudson.util.FormValidation;
import jenkins.model.Jenkins;
import jenkins.model.ModelObjectWithChildren;
import jenkins.model.ModelObjectWithContextMenu.ContextMenu;
import jenkins.util.Timer;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
@@ -55,10 +58,13 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.json.JSONObject;

import static hudson.init.InitMilestone.JOB_LOADED;

/**
* Serves as the top of {@link Computer}s in the URL hierarchy.
* <p>
@@ -397,6 +403,16 @@ public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter fi
*/
public static void initialize() {}

@Initializer(after= JOB_LOADED)
public static void init() {
// start monitoring nodes, although there's no hurry.
Timer.get().schedule(new SafeTimerTask() {
public void doRun() {
ComputerSet.initialize();
}
}, 10, TimeUnit.SECONDS);
}

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

static {
@@ -23,16 +23,20 @@
*/
package hudson.model;

import hudson.init.Initializer;
import hudson.triggers.SafeTimerTask;
import hudson.triggers.Trigger;
import hudson.ExtensionPoint;
import hudson.Extension;
import hudson.ExtensionList;
import jenkins.model.Jenkins;
import jenkins.util.Timer;

import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.Random;
import java.util.Timer;

import static hudson.init.InitMilestone.JOB_LOADED;

/**
* Extension point to perform a periodic task in Hudson (through {@link Timer}.)
@@ -89,6 +93,14 @@ public long getInitialDelay() {
return Jenkins.getInstance().getExtensionList(PeriodicWork.class);
}

@Initializer(after= JOB_LOADED)
public static void init() {
// start all PeriodicWorks
for (PeriodicWork p : PeriodicWork.all()) {
Timer.get().scheduleAtFixedRate(p, p.getInitialDelay(), p.getRecurrencePeriod(), TimeUnit.MILLISECONDS);
}
}

// time constants
protected static final long MIN = 1000*60;
protected static final long HOUR =60*MIN;
@@ -66,6 +66,7 @@
import hudson.model.queue.CauseOfBlockage.BecauseNodeIsBusy;
import hudson.model.queue.WorkUnitContext;
import hudson.security.ACL;
import jenkins.util.Timer;
import hudson.triggers.SafeTimerTask;
import hudson.triggers.Trigger;
import hudson.util.OneShotEvent;
@@ -93,7 +94,6 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Timer;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
@@ -2072,10 +2072,7 @@ public String toString(Object item) {
this.queue = new WeakReference<Queue>(queue);

long interval = 5000;
Timer timer = Trigger.timer;
if (timer != null) {
timer.schedule(this, interval, interval);
}
Timer.get().scheduleWithFixedDelay(this, interval, interval, TimeUnit.MILLISECONDS);
}

protected void doRun() {
@@ -29,16 +29,16 @@
import jenkins.model.Jenkins;
import hudson.model.ComputerSet;
import hudson.model.AdministrativeMonitor;
import hudson.triggers.Trigger;
import hudson.triggers.SafeTimerTask;
import hudson.slaves.OfflineCause;
import jenkins.util.Timer;

import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

@@ -87,14 +87,12 @@ protected AbstractNodeMonitorDescriptor(Class<? extends NodeMonitor> clazz, long
}

private void schedule(long interval) {
Timer timer = Trigger.timer;
if (timer != null) {
timer.scheduleAtFixedRate(new SafeTimerTask() {
Timer.get()
.scheduleAtFixedRate(new SafeTimerTask() {
public void doRun() {
triggerUpdate();
}
}, interval, interval);
}
}, interval, interval, TimeUnit.MILLISECONDS);
}

/**
@@ -23,18 +23,14 @@
*/
package hudson.triggers;

import static hudson.init.InitMilestone.JOB_LOADED;
import hudson.DependencyRunner;
import hudson.DependencyRunner.ProjectRunnable;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.init.Initializer;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.AperiodicWork;
import hudson.model.Build;
import hudson.model.ComputerSet;
import hudson.model.Describable;
import hudson.scheduler.Hash;
import jenkins.model.Jenkins;
@@ -45,7 +41,6 @@
import hudson.model.TopLevelItemDescriptor;
import hudson.scheduler.CronTab;
import hudson.scheduler.CronTabList;
import hudson.util.DoubleLaunchChecker;

import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
@@ -56,7 +51,6 @@
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -279,34 +273,12 @@ public void run(AbstractProject p) {
* Initialized and cleaned up by {@link jenkins.model.Jenkins}, but value kept here for compatibility.
*
* If plugins want to run periodic jobs, they should implement {@link PeriodicWork}.
*
* @deprecated Use {@link jenkins.util.Timer#get()} instead.
*/
@SuppressWarnings("MS_SHOULD_BE_FINAL")
public static @CheckForNull Timer timer;

@Initializer(after=JOB_LOADED)
public static void init() {
new DoubleLaunchChecker().schedule();

Timer _timer = timer;
if (_timer != null) {
// start all PeridocWorks
for(PeriodicWork p : PeriodicWork.all()) {
_timer.scheduleAtFixedRate(p,p.getInitialDelay(),p.getRecurrencePeriod());
}

// start all AperidocWorks
for(AperiodicWork p : AperiodicWork.all()) {
_timer.schedule(p,p.getInitialDelay());
}

// start monitoring nodes, although there's no hurry.
_timer.schedule(new SafeTimerTask() {
public void doRun() {
ComputerSet.initialize();
}
}, 1000*10);
}
}
@Deprecated
public static @CheckForNull java.util.Timer timer;

/**
* Returns all the registered {@link Trigger} descriptors.
@@ -23,24 +23,28 @@
*/
package hudson.util;

import hudson.init.Initializer;
import jenkins.model.Jenkins;
import hudson.triggers.SafeTimerTask;
import hudson.triggers.Trigger;
import jenkins.util.Timer;
import org.apache.commons.io.FileUtils;
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import javax.servlet.ServletContext;

import static hudson.init.InitMilestone.JOB_LOADED;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.util.Timer;

/**
* Makes sure that no other Hudson uses our <tt>JENKINS_HOME</tt> directory,
@@ -146,14 +150,18 @@ public String getCollidingId() {
public void schedule() {
// randomize the scheduling so that multiple Hudson instances will write at the file at different time
long MINUTE = 1000*60;
Timer timer = Trigger.timer;
if (timer != null) {
timer.schedule(new SafeTimerTask() {

Timer.get()
.schedule(new SafeTimerTask() {
protected void doRun() {
execute();
}
},(random.nextInt(30)+60)*MINUTE);
}
}, (random.nextInt(30) + 60) * MINUTE, TimeUnit.MILLISECONDS);
}

@Initializer(after= JOB_LOADED)
public static void init() {
new DoubleLaunchChecker().schedule();
}

/**

0 comments on commit 44ee0bb

Please sign in to comment.