package no.priv.garshol.duke.server;
import java.util.Properties;
import no.priv.garshol.duke.DukeException;
/**
* A basic timer implementation that will work in any context, but
* which does not (unfortunately) provide managed threads in more
* advanced servlet containers. For that, look at CommonJTimer.
*/
public class BasicTimer implements DukeTimer, Runnable {
private DukeController controller;
private int check_interval;
private int sleep_interval;
private boolean keep_running;
// --- Setup
public BasicTimer() {
this.sleep_interval = 100; // default
}
// --- DukeTimer implementation
public void init(Properties props) {
// don't need to do anything
}
public void spawnThread(DukeController controller, int check_interval) {
if (this.controller != null)
throw new DukeException("Timer thread already running!");
this.controller = controller;
this.check_interval = check_interval * 1000; // convert to ms
keep_running = true;
// spawn away
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.start();
}
public boolean isRunning() {
return keep_running;
}
public void stop() {
controller = null;
keep_running = false;
}
// --- Runnable implementation
public void run() {
while (keep_running) {
try {
// tell controller to do some real work for a change
controller.process();
// waiting check_interval ms, while taking sleep_interval ms
// long naps so we can break off faster if the server is shut
// down
long wait_start = System.currentTimeMillis();
do {
Thread.sleep(sleep_interval);
} while (keep_running &&
(System.currentTimeMillis() - wait_start) < check_interval);
} catch (Throwable e) {
controller.reportError(e);
try {
Thread.sleep(getErrorWaitInteral()); // wait a good while, then retry
} catch (InterruptedException e2) {
}
}
}
controller.reportStopped();
}
// --- Internal methods
private int getErrorWaitInteral() {
return check_interval * 6;
}
}