Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
92 lines (78 sloc) 2.72 KB
package jaci.openrio.module.routines;
import jaci.openrio.toast.core.thread.HeartbeatListener;
import jaci.openrio.toast.lib.log.Logger;
import jaci.openrio.toast.lib.state.ConcurrentVector;
/**
* A faster-running version of the Heartbeat suitable for Routines recording.
*
* @author Jaci
*/
public class RoutineHeartbeat implements Runnable {
static ConcurrentVector<HeartbeatListener> aorta = new ConcurrentVector<>();
static long heart_rate = 20;
static Logger nervous_system;
int skipped_beats;
static boolean running;
int consecutive;
@Override
public void run() {
while (true) {
try {
running = true;
long start = System.currentTimeMillis();
aorta.tick();
for (HeartbeatListener artery : aorta)
artery.onHeartbeat(skipped_beats);
long end = System.currentTimeMillis();
long tick_time = end - start;
skipped_beats = 0;
if (tick_time < heart_rate) {
Thread.sleep(heart_rate - tick_time);
consecutive = 0;
} else if (tick_time > heart_rate) {
skipped_beats = (int)(tick_time / heart_rate);
consecutive++;
if (consecutive < 3) {
log().warn(String.format("Heartbeat skipped %s beats, (took %sms of max %sms)", skipped_beats, tick_time, heart_rate));
} else if (consecutive == 3) {
log().warn("Too many consecutive skipped Heartbeats, suppressing log.");
}
Thread.sleep(tick_time % heart_rate);
}
if (aorta.size() == 0) {
running = false;
return;
}
} catch (Exception e) {}
}
}
/**
* Get the logger for the Heartbeat
*/
public static Logger log() {
if (nervous_system == null)
nervous_system = new Logger("Routines", Logger.ATTR_TIME);
return nervous_system;
}
/**
* Add a listener to the Heartbeat. This can be done at any time
*/
public static void add(HeartbeatListener artery) {
aorta.addConcurrent(artery);
checkActive();
}
/**
* Remove a listener from the Heartbeat. This can be done at any time.
*/
public static void remove(HeartbeatListener artery) {
aorta.removeConcurrent(artery);
}
static Thread heart;
static void checkActive() {
if (!running) {
heart = new Thread(new RoutineHeartbeat());
heart.setName("Routines");
heart.start();
}
}
}