package cgl.iotcloud.core.master;
import cgl.iotcloud.core.master.events.MSiteEvent;
import com.google.common.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
public class HeartBeats {
private static Logger LOG = LoggerFactory.getLogger(HeartBeats.class);
int retries = 1;
private Map<String, Timer> hearBeatTasks = new HashMap<String, Timer>();
private EventBus siteEvents;
public HeartBeats(EventBus siteEvents) {
this.siteEvents = siteEvents;
}
public void setRetries(int retries) {
this.retries = retries;
}
public void scheduleForSite(String id, String host, int port) {
LOG.info("Heart beats scheduled for site {}", id);
HearBeatTask task = new HearBeatTask(id, host, port);
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, 0, 500);
hearBeatTasks.put(id, timer);
}
public void stopForSite(String id) {
Timer timer = hearBeatTasks.get(id);
if (timer != null) {
timer.cancel();
}
}
private class HearBeatTask extends TimerTask {
String host;
int port;
String id;
SiteState status = SiteState.ACTIVE;
private HearBeatTask(String id, String host, int port) {
this.host = host;
this.port = port;
this.id = id;
}
public void run() {
boolean success = false;
int tries = 0;
while (!success && tries < retries) {
SiteClient client = null;
try {
client = new SiteClient(host, port);
boolean result = client.sendHearBeat();
if (result) success = true;
} catch (Exception e) {
LOG.debug("Sensor site not reachable", e);
success = false;
} finally {
if (client != null) {
client.close();
}
}
tries++;
if (!success && tries >= retries && status != SiteState.DEACTIVATED) {
// remove the site and its sensors from the master context
MSiteEvent event = new MSiteEvent(id, SiteState.DEACTIVATED);
status = SiteState.DEACTIVATED;
siteEvents.post(event);
LOG.info("Detected that the site with host: {} and port: {} is no longer active", host, port);
} else if (success && status == SiteState.DEACTIVATED) {
MSiteEvent event = new MSiteEvent(id, SiteState.ACTIVE);
status = SiteState.ACTIVE;
siteEvents.post(event);
LOG.info("Site with with host: {} and port: {} came online", host, port);
}
}
}
}
}