diff --git a/main/src/com/google/refine/RefineServlet.java b/main/src/com/google/refine/RefineServlet.java index 50bf557aa..4e0a09d09 100644 --- a/main/src/com/google/refine/RefineServlet.java +++ b/main/src/com/google/refine/RefineServlet.java @@ -41,8 +41,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -80,23 +81,19 @@ public class RefineServlet extends Butterfly { static final private Map commands = new HashMap(); // timer for periodically saving projects - static private Timer _timer = new Timer("autosave"); + static private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); static final Logger logger = LoggerFactory.getLogger("refine"); - static final protected long s_autoSavePeriod = 1000 * 60 * 5; // 5 minutes + static final protected long AUTOSAVE_PERIOD = 5; // 5 minutes - static protected class AutoSaveTimerTask extends TimerTask { + static protected class AutoSaveTimerTask implements Runnable { @Override public void run() { try { ProjectManager.singleton.save(false); // quick, potentially incomplete save - } finally { - if (_timer != null) { - _timer.schedule(new AutoSaveTimerTask(), s_autoSavePeriod); - // we don't use scheduleAtFixedRate because that might result in - // bunched up events when the computer is put in sleep mode - } + } catch (final Throwable e) { + // Not the best, but we REALLY want this to keep trying } } } @@ -134,7 +131,8 @@ public class RefineServlet extends Butterfly { FileProjectManager.initialize(s_dataDir); ImportingManager.initialize(this); - _timer.schedule(new AutoSaveTimerTask(), s_autoSavePeriod); + service.scheduleWithFixedDelay(new AutoSaveTimerTask(), AUTOSAVE_PERIOD, + AUTOSAVE_PERIOD, TimeUnit.MINUTES); logger.trace("< initialize"); } diff --git a/main/src/com/google/refine/importing/ImportingManager.java b/main/src/com/google/refine/importing/ImportingManager.java index 3752c7b9f..2111a1af6 100644 --- a/main/src/com/google/refine/importing/ImportingManager.java +++ b/main/src/com/google/refine/importing/ImportingManager.java @@ -35,6 +35,8 @@ package com.google.refine.importing; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -43,8 +45,9 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.json.JSONException; @@ -104,29 +107,25 @@ public class ImportingManager { final static public Map controllers = new HashMap(); // timer for periodically deleting stale importing jobs - static private Timer _timer; + static private ScheduledExecutorService service; - final static private long s_timerPeriod = 1000 * 60 * 10; // 10 minutes - final static private long s_stalePeriod = 1000 * 60 * 60; // 60 minutes + final static private long TIMER_PERIOD = 10; // 10 minutes + final static private long STALE_PERIOD = 60; // 60 minutes - static private class CleaningTimerTask extends TimerTask { + static private class CleaningTimerTask implements Runnable { @Override public void run() { - try { - cleanUpStaleJobs(); - } finally { - _timer.schedule(new CleaningTimerTask(), s_timerPeriod); - // we don't use scheduleAtFixedRate because that might result in - // bunched up events when the computer is put in sleep mode - } + // An exception here will keep future runs of this task from happening, + // but won't affect other timer tasks + cleanUpStaleJobs(); } } static public void initialize(RefineServlet servlet) { ImportingManager.servlet = servlet; - _timer = new Timer("autosave"); - _timer.schedule(new CleaningTimerTask(), s_timerPeriod); + service = Executors.newSingleThreadScheduledExecutor(); + service.scheduleWithFixedDelay(new CleaningTimerTask(), TIMER_PERIOD, TIMER_PERIOD, TimeUnit.MINUTES); } static public void registerFormat(String format, String label) { @@ -289,13 +288,13 @@ public class ImportingManager { static private void cleanUpStaleJobs() { long now = System.currentTimeMillis(); - HashSet keys; + Collection keys; synchronized(jobs) { - keys = new HashSet(jobs.keySet()); + keys = new ArrayList(jobs.keySet()); } for (Long id : keys) { ImportingJob job = jobs.get(id); - if (job != null && !job.updating && now - job.lastTouched > s_stalePeriod) { + if (job != null && !job.updating && now - job.lastTouched > STALE_PERIOD) { job.dispose(); jobs.remove(id); logger.info("Disposed " + id);