package com.github.martinprillard.shavadoop.master.tasktracker; import java.io.IOException; import java.net.ServerSocket; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import com.github.martinprillard.shavadoop.master.LaunchShufflingMap; import com.github.martinprillard.shavadoop.master.LaunchSplitMapping; import com.github.martinprillard.shavadoop.network.SSHManager; import com.github.martinprillard.shavadoop.slave.Slave; import com.github.martinprillard.shavadoop.util.Constant; /** * * @author martin prillard * */ public class TaskTracker extends Thread { private ExecutorService es; private ExecutorService esTaskTracker; private String hostMaster; private Map<Thread, List<String>> taskHistory = new HashMap<Thread, List<String>>(); private SSHManager sm; private Map<String, String> dictionaryReducing = null; private int portTaskTracker; private ServerSocket ss = null; private String nbWorker; public TaskTracker(SSHManager _sm, ExecutorService _es, int _portTaskTracker, String _nbWorker, Map<String, String> _dictionaryReducing) { sm = _sm; es = _es; hostMaster = sm.getHostFull(); portTaskTracker = _portTaskTracker; nbWorker = _nbWorker; dictionaryReducing = _dictionaryReducing; esTaskTracker = Executors.newCachedThreadPool(); try { ss = new ServerSocket(portTaskTracker); ss.setReuseAddress(true); } catch (IOException e) { e.printStackTrace(); } } /** * Add worker's task to the task tracker * * @param thread * @param host * @param idWorker * @param taskName * @param fileToTreat * @param key */ public void addTask(Thread thread, String host, String idWorker, String taskName, String fileToTreat, String key) { List<String> taskInfos = getTaskInfos(host, idWorker, taskName, fileToTreat, key); taskHistory.put(thread, taskInfos); esTaskTracker.execute(new StateSlaveManager(this, ss, sm, thread, taskInfos)); } /** * Get task infos * * @param host * @param idWorker * @param taskName * @param fileToTreat * @param key * @return task infos */ private List<String> getTaskInfos(String host, String idWorker, String taskName, String fileToTreat, String key) { List<String> taskInfos = new ArrayList<String>(); taskInfos.add(host); taskInfos.add(idWorker); taskInfos.add(taskName); taskInfos.add(fileToTreat); taskInfos.add(key); return taskInfos; } /** * Remove a worker's task of the task tracker * * @param thread */ public void removeTask(Thread thread) { taskHistory.remove(thread); // if all thread's task are finished if (taskHistory.isEmpty()) { esTaskTracker.shutdown(); es.shutdown(); } } public void run() { if (Constant.MODE_DEBUG) System.out.println("TASK_TRACKER : START"); check(); if (Constant.MODE_DEBUG) System.out.println("TASK_TRACKER : END"); } /** * Check if the workers are alive */ public void check() { // wait all state slave manager threads try { esTaskTracker.awaitTermination(Constant.THREAD_MAX_LIFETIME, TimeUnit.MINUTES); } catch (InterruptedException e) { e.printStackTrace(); } try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } /** * Relaunch a worker's task * * @param thread * @param newHost * @param idWorker * @param taskName * @param fileTask * @param key */ public void relaunchTask(Thread thread, String newHost, String idWorker, String taskName, String fileTask, String key) { // if needed, modify the dictionary file if (dictionaryReducing != null) { // erase old information of the worker failed dictionaryReducing.put(idWorker, newHost); } // launch the task Thread newTask = null; switch (taskName) { case Slave.SPLIT_MAPPING_FUNCTION: newTask = new LaunchSplitMapping(sm, nbWorker, newHost, fileTask, hostMaster, idWorker); es.execute(newTask); break; case Slave.SHUFFLING_MAP_FUNCTION: newTask = new LaunchShufflingMap(sm, nbWorker, newHost, fileTask, hostMaster, idWorker); es.execute(newTask); break; } // add this new task addTask(newTask, newHost, idWorker, taskName, fileTask, key); // interrupt the old thread thread.interrupt(); // remove from the map removeTask(thread); } }