HeartBeat Assignment
We were given the following assignment:
Application: The App is instantiated with the Controller as an argument. When started, the App prints “App started” on the screen and registers itself at the Controller. Every 2 seconds, the App sends a heartbeat to the Controller and prints “Heartbeat” onto the screen including the current time. With a probability of 10 percent the heartbeat is not sent to the Controller.
Controller: If the Controller receives a heartbeat by a registered App, it prints “acknowledged” on the screen. If the next heartbeat after a heartbeat or after registration is not received within 2.5 seconds, the controller kills the current instance of the App, prints “App killed” and creates and runs a new instance of App.
This was my code in Java, with some changes made after submission:
package np.com.saurab.prog; import java.util.Date; import java.util.Random; public class Controller implements Runnable { App app; static Controller controller; static Thread runner; int timeInterval = 0; Controller() { runner = new Thread(this); } public void start() { runner.start(); } public void registerApp(App app) { this.app = app; } @Override public void run() { try{ while(true){ if (null != app) { timeInterval = app.getHeartBeat(); if(timeInterval<2500){ System.out.println("acknowledged"); app.setHeartBeat(false); }else{ System.out.println("App Killed"); app.stopThread(); app = null; app = new App(controller); app.start(); } timeInterval = 0; } } }catch(Exception e){ } } public static void main(String[] args) { controller = new Controller(); controller.start(); App newApp = new App(controller); newApp.start(); } } class App implements Runnable { private boolean heartBeat; private Controller controller; private static Thread runner; private int time = 0; App(Controller controller) { this.controller = controller; this.setHeartBeat(false); this.setTime(0); runner = new Thread(this); } public void start() { runner.start(); } public void stopThread() { runner = null; } @Override public void run() { System.out.println("App Started"); controller.registerApp(this); Random random = new Random(); float randomFloat = 0F; int intervalTime = 0; while (true) { try { randomFloat = random.nextFloat(); System.out.println("RandomFloat : "+randomFloat); intervalTime = (randomFloat <= 0.1) ? 2500 : 2000; Thread.sleep(intervalTime); putHeartBeat(intervalTime); } catch (Exception e) { e.printStackTrace(); } } } private synchronized void putHeartBeat(int intervalTime) throws InterruptedException { while (this.isHeartBeat()) wait(); if (intervalTime < 2500) { System.out.println("HeartBeat : " + new Date()); } this.setHeartBeat(true); this.setTime(intervalTime); notify(); } public synchronized int getHeartBeat() throws InterruptedException { notify(); while (!this.isHeartBeat()) wait(); notify(); return this.getTime(); } public boolean isHeartBeat() { return heartBeat; } public void setHeartBeat(boolean heartBeat) { this.heartBeat = heartBeat; } public int getTime() { return time; } public void setTime(int time) { this.time = time; } }
And the output was seen as something like this:
App Started HeartBeat : Sat Dec 14 12:11:33 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:35 CET 2013 acknowledged App Killed App Started HeartBeat : Sat Dec 14 12:11:40 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:42 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:44 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:46 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:48 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:50 CET 2013 acknowledged HeartBeat : Sat Dec 14 12:11:52 CET 2013 acknowledged App Killed App Started
I don’t know the best way to do it. However, this is what I did, and it worked.