/********************************************************** * Doctoral Program in Science and Information Technology * Department of Informatics Engineering * University of Coimbra ********************************************************** * Large Scale Concurrent Systems * * Pedro Alexandre Mesquita Santos Martins - pamm@dei.uc.pt * Nuno Manuel dos Santos Antunes - nmsa@dei.uc.pt **********************************************************/ package org.graphdht.openchord; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import org.graphdht.dht.HTService; import static org.graphdht.openchord.DHTConstants.*; /** * * * * * @param <K> * @param <V> * @author nmsa@dei.uc.pt */ public class DHTServer implements HTService<Long, byte[]> { private final DHTChord chord; private final int port; private Logger logger; private long comTime; private long worTime; private long comCount = 0; private long worCount = 0; public DHTServer(DHTChord chord) { super(); this.chord = chord; this.port = GDHT_OPENCHORD_SERVER_ADD + (chord.getURL().getPort() > 0 ? chord.getURL().getPort() : GDHT_OPENCHORD_I_PORT); logger = new Logger(); } public void start() throws IOException { ServerSocket s = new ServerSocket(port); System.out.println("DHTServer listening at: " + port); while (true) { new ListeningThread(s.accept()); } } public class Logger extends Thread { private FileOutputStream logFile; private boolean running = true; private StringBuffer buffer; private int p; private int g; private int other; private Logger() { running = true; buffer = new StringBuffer("\nStarted!\n"); try { new File("../log/").mkdir(); logFile = new FileOutputStream("../log/DHTServer-" + port + "-debug.log", true); } catch (Exception ex) { System.out.println("Cannot start log"); } this.start(); } public void shutdown() { running = false; } @Override public void run() { StringBuffer local; while (running) { try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException ie) { } synchronized (this) { local = buffer; buffer = new StringBuffer(new Date().toString()); buffer.append("\n"); } local.append("P :").append(p); local.append("\tG :").append(g); local.append("\tOT :").append(other); local.append("\tCOM :").append(comTime).append(" AVG:").append((double) comTime / (double) comCount); local.append("\tWORK:").append(worTime).append(" AVG:").append((double) worTime / (double) worCount); local.append("\n"); try { logFile.write(local.toString().getBytes()); } catch (IOException io) { } } } private void logE(Exception e) { buffer.append(e); buffer.append("\n"); } private void logG(String last) { g++; } private void logP(String last) { p++; } private void logO() { other++; } } public class ListeningThread extends Thread { private Socket socket; private ListeningThread(Socket socket) { this.socket = socket; this.start(); } @Override public void run() { long one, two = 0; System.out.println("DHTServer thread is spawning after receiving a socket"); ObjectInputStream is; ObjectOutputStream os; try { os = new ObjectOutputStream(socket.getOutputStream()); is = new ObjectInputStream(socket.getInputStream()); } catch (IOException ex) { ex.printStackTrace(); return; } while (true) { Message message = null; try { one = System.currentTimeMillis(); message = (Message) is.readObject(); two = System.currentTimeMillis(); comTime += two - one; comCount++; } catch (IOException ex) { try { socket.close(); } catch (IOException ex1) { logger.logE(ex1); } return; } catch (ClassNotFoundException ex) { ex.printStackTrace(); } if (message == null) { System.out.println(socket.getPort() + " message == null"); if (socket.isClosed()) { System.out.println(socket.getPort() + " CLOSED..."); } } else { byte[] response = null; switch (message.type) { case GET: response = get(message.key); one = System.currentTimeMillis(); worTime += one - two; worCount++; try { os.writeObject(response); } catch (IOException io) { io.printStackTrace(); } two = System.currentTimeMillis(); comTime += two - one; comCount++; break; case PUT: put(message.key, message.byteArray); break; case REMOVE: remove(message.key); break; case PUTALL: putAll(null); break; case GETALL: getAllValues(); break; } one = System.currentTimeMillis(); worTime += one - two; worCount++; } } } } @Override public byte[] get(Long key) { logger.logG(key.toString()); try { return (byte[]) chord.get(new DHTKey(key)); // HERE } catch (Exception e) { logger.logE(e); e.printStackTrace(); return null; } } @Override public void put(Long key, byte[] value) { logger.logP(key.toString()); try { chord.put(new DHTKey(key), value); } catch (Exception e) { logger.logE(e); e.printStackTrace(); } } @Override public void remove(Long key) { logger.logO(); try { chord.remove(new DHTKey(key)); } catch (Exception e) { logger.logE(e); e.printStackTrace(); } } @Override public void putAll(Map<Long, byte[]> values) { logger.logO(); try { Map<DHTKey, Serializable> map = new HashMap<DHTKey, Serializable>(); for (Long key : values.keySet()) { map.put(new DHTKey(key), values.get(key)); } chord.putAll(map); } catch (Exception e) { logger.logE(e); e.printStackTrace(); } } @Override public Iterable<byte[]> getAllValues() { logger.logO(); return null; } @Override public void shutdown() { } }