Package threePhaseModule

Source Code of threePhaseModule.ThreePhaseNetworkManager

package threePhaseModule;

import engine.Main;
import gui.GUIManager;

import java.net.ServerSocket;
import java.util.HashMap;
import java.util.PriorityQueue;

import communication.NetworkManager;
import communication.ReceiveManager;
import communication.Sender;
import communication.TextMessage;

public class ThreePhaseNetworkManager extends NetworkManager {
  public static final int PHASE_1 = 1;
  public static final int PHASE_2 = 2;
  public static final int PHASE_3 = 3;

  public int peerIndex, mtag;
  private HashMap<Integer, Sender> senders;
  private ReceiveManager receiver;
  public GUIManager gui;
  public long clock, priority;

  public PriorityQueue<ThreePhaseTextMessage> tempQueue;
  public HashMap<Integer, Status> tempTSS;

  public ThreePhaseNetworkManager(int peerIndex) {
    this.peerIndex = peerIndex;

    /* Initialize the clock */
    this.clock = 0;
    this.mtag = peerIndex * 10000;
    this.priority = 0;

    /* Initialize the timestamp sorted queues */
    ThreePhaseComparator tpc = new ThreePhaseComparator();
    tempQueue = new PriorityQueue<ThreePhaseTextMessage>(10000, tpc);

    /* Initialize the Hashmap of temporary timestamps */
    tempTSS = new HashMap<Integer, Status>();
  }

  @Override
  public synchronized void insert(int pos, char c) {
    System.out.println("I am going to broadcast an insertion " + c + " at " + pos);
    updateClock(clock + 1);
    int messageTag = mtag++;

    /* Create the message and send it */
    ThreePhaseTextMessage tm = new ThreePhaseTextMessage(pos, c, TextMessage.INSERT, peerIndex, null,
        messageTag, clock, PHASE_1, false);
    for (int i = 0; i < Main.peerCount; i++) {
      if (i == peerIndex)
        continue;
      senders.get(i).send(tm);
    }

    /* Save the initial temporary timestamp for the message */
    tempTSS.put(messageTag, new Status(0, new Long(0)));
  }

  @Override
  public synchronized void delete(int pos) {
    System.out.println("I am going to broadcast a deletion at " + pos);
    updateClock(clock + 1);
    int messageTag = mtag++;

    /* Create the message and send it */
    ThreePhaseTextMessage tm = new ThreePhaseTextMessage(pos, 'q', TextMessage.DELETE, peerIndex, null,
        messageTag, clock, PHASE_1, false);
    for (int i = 0; i < Main.peerCount; i++) {
      if (i == peerIndex)
        continue;
      senders.get(i).send(tm);
    }

    /* Save the initial temporary timestamp for the message */
    tempTSS.put(messageTag, new Status(0, new Long(0)));
  }


  /* Create the sender and receiver threads */
  public void initiateCommThreads() {
    System.out.println("3 Phase Network Manager creates the threads");

    /* Create listener and sender threads */
    senders = new HashMap<Integer, Sender>(Main.peerCount - 1);
    try {
      /* Create the listener socket */
      ServerSocket listener = new ServerSocket(Main.ports.get(peerIndex));
      receiver = new ReceiveManager(listener, this);


      /* Create the sender threads */
      for (int i = 0; i < Main.peerCount; i++) {
        if (i == peerIndex)
          continue;

        senders.put(i, new Sender(Main.IPAdresses.get(i), Main.ports.get(i)));
      }
    } catch (Exception e) {
      System.out.println("Unable to start sockets");
      e.printStackTrace();
    }
  }


  @Override
  public void connectToGUI(GUIManager gui) {
    this.gui = gui;
    initiateCommThreads();
  }

  public void run() {
    System.out.println("3 Phase Network manager " + peerIndex + " starts the threads ");


    /* Start the receiver and sender sockets */
    receiver.start();
    for (int i = 0; i < Main.peerCount; i++) {
      if (i == peerIndex)
        continue;
      senders.get(i).start();
    }
  }
 
 
  private void handlePhase1(TextMessage tm) {
    ThreePhaseTextMessage tptm = (ThreePhaseTextMessage)tm;
   
    /* Update the priority */
    priority = (priority + 1) > tptm.timestamp ? priority + 1 : tptm.timestamp;
    tptm.timestamp = priority;
   
    /* Insert the message in the temporary queue */
    tempQueue.add(tptm);
   
    /* Send Phase 2 message back to the sender */
    tptm.phase = PHASE_2;
    senders.get(tm.sender).send(tptm);
  }

 
  private void handlePhase2(TextMessage tm) {
    ThreePhaseTextMessage tptm = (ThreePhaseTextMessage)tm;
    System.out.println("Handling Phase 2 for " + tptm);
    Status status = tempTSS.get(new Integer(tptm.tag));
    long tempTS = status.tempTS;

    /* Update the temporary timestamp */
    status.tempTS = tempTS > tptm.timestamp ? tempTS : tptm.timestamp;
    status.count++;
    tempTSS.put(tptm.tag, status);

    /* Check if we got response from all the other peers */
    if (status.count == Main.connectedPeers) {
      System.out.println("Got all the Phase 2 messages, going to send Phase 3");
      tempTSS.remove(tptm.tag);

      /* Send Phase 3 message */
      tptm.timestamp = status.tempTS;
      tptm.phase = PHASE_3;
      for (int i = 0; i < Main.peerCount; i++) {
        if (i == peerIndex)
          continue;
        senders.get(i).send(tm);
      }
     
      /* Update the clock */
      updateClock(clock > status.tempTS ? clock : status.tempTS);
    }
  }


  private void handlePhase3(TextMessage tm) {
    ThreePhaseTextMessage tptm = (ThreePhaseTextMessage)tm;
    ThreePhaseTextMessage initial = null;
   
    /* Identify the phase 2 entry in the temporary queue */
    for (ThreePhaseTextMessage entry:tempQueue)
      if (entry.tag == tptm.tag) {
        initial = entry;
        tempQueue.remove(entry);
        break;
      }
   
    /* Mark the initial message deliverable */
    if (initial == null) {
      System.out.println("ERROR[Phase 3]: no initial Phase 2 message in temporary queue");
      return;
    }
    initial.deliverable = true;
   
    /* Update the message timestamp and add it back to the temp queue */
    initial.timestamp = tptm.timestamp;
    tempQueue.add(initial);
   
    /* Check for deliverable elements */
    if (tempQueue.peek().tag == initial.tag) {
      printQueue();
      deliverMessage(tm);
      tempQueue.poll();
      updateClock((clock > tptm.timestamp ? clock : tptm.timestamp) + 1);
     
      while (!tempQueue.isEmpty() && tempQueue.peek().deliverable) {
        ThreePhaseTextMessage msg = tempQueue.poll();
        deliverMessage(msg);
        updateClock((clock > msg.timestamp ? clock : msg.timestamp) + 1);
      }
    }
  }
 
  private void printQueue() {
    System.out.println("Printing queue");
    for (ThreePhaseTextMessage tm:tempQueue) {
      System.out.println("Q " + tm);
    }
  }

  @Override
  public synchronized void onReceive(TextMessage tm) {
    ThreePhaseTextMessage tptm = (ThreePhaseTextMessage)tm;

    switch (tptm.phase) {
    case PHASE_1:
      /* Handle Phase 1 responses */
      handlePhase1(tm);
      break;

    case PHASE_2:
      /* Handle Phase 2 responses */
      handlePhase2(tm);
      break;

    case PHASE_3:
      /* Handle Phase 3 responses */
      handlePhase3(tm);
      break;
    }

  }

  @Override
  public GUIManager getGUI() {
    return gui;
  }

  /* Deliver message to GUI */
  public void deliverMessage(TextMessage request) {

    /* Perform action */
    switch (request.type) {
    case TextMessage.DELETE:
      gui.deleteChar(request.pos);
      break;

    case TextMessage.INSERT:
      gui.insertChar(request.pos, request.c);
      break;
    }
  }
 
  public synchronized void updateClock(long value) {
    clock = value;
  }
}
TOP

Related Classes of threePhaseModule.ThreePhaseNetworkManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.