Switch from TimerTask to ScheduledExecutorService for more robustness
This commit is contained in:
parent
25a3de410f
commit
4529310237
@ -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<String, Command> commands = new HashMap<String, Command>();
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
@ -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<String, ImportingController> controllers = new HashMap<String, ImportingController>();
|
||||
|
||||
// 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<Long> keys;
|
||||
Collection<Long> keys;
|
||||
synchronized(jobs) {
|
||||
keys = new HashSet<Long>(jobs.keySet());
|
||||
keys = new ArrayList<Long>(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);
|
||||
|
Loading…
Reference in New Issue
Block a user