package com.github.martinprillard.shavadoop.master.tasktracker;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.github.martinprillard.shavadoop.network.SSHManager;
import com.github.martinprillard.shavadoop.util.Constant;
/**
*
* @author martin prillard
*
*/
public class StateSlaveManager extends Thread {
private ServerSocket ss;
private TaskTracker ts;
private Thread thread;
private List<String> taskList;
private SSHManager sm;
private boolean taskFinished = false;
private boolean workerDied = false;
private String host;
private String idWorker;
private String taskName;
private String fileTask;
private String key;
public StateSlaveManager(TaskTracker _ts, ServerSocket _ss, SSHManager _sm, Thread _taskThread, List<String> _taskList) {
ts = _ts;
ss = _ss;
sm = _sm;
thread = _taskThread;
taskList = _taskList;
host = taskList.get(0);
idWorker = taskList.get(1);
taskName = taskList.get(2);
fileTask = taskList.get(3);
key = taskList.get(4);
}
public void run() {
// the distant worker is dead
if (!sm.isLocal(host) && !sm.isAlive(host)) {
caseWorkerDied();
// if the worker is alive
} else {
Socket socket;
try {
socket = ss.accept();
while (!taskFinished) {
// wait between two requests check
try {
Thread.sleep(Constant.TASK_TRACKER_FREQ);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
// we trie to send request to the slave to know if it's alive or not
if (!workerDied) {
ExecutorService esCheckTimer = Executors.newCachedThreadPool();
esCheckTimer.execute(new CheckStateSlave(this, socket));
esCheckTimer.shutdown();
try {
esCheckTimer.awaitTermination(Constant.TASK_TRACKER_ANSWER_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* In the case where the worker task is finished
*/
public void caseWorkerTaskIsFinished() {
ts.removeTask(thread);
taskFinished = true;
}
/**
* In the case where the worker is dead
*/
public void caseWorkerDied() {
workerDied = true;
if (Constant.MODE_DEBUG)
System.out.println("TASK_TRACKER : worker " + idWorker + " (" + host + ") died");
String hostFail = host;
// we get an other worker
List<String> hostWorker = sm.getHostAliveCores(1, true, false);
if (hostWorker.size() == 1) {
host = hostWorker.get(0);
} else {
// it's the master
host = sm.getHostFullMaster();
}
// we relaunch the task on an other worker
if (Constant.MODE_DEBUG)
System.out.println("TASK_TRACKER : redirect " + taskName + " from worker " + idWorker + " (" + hostFail + ") task on " + host);
ts.relaunchTask(thread, host, idWorker, taskName, fileTask, key);
}
public boolean getTaskFinished() {
return this.taskFinished;
}
}