예제 #1
0
  /**
   * This method sends a message to the process; this process also sets logical clock
   *
   * @param workMess
   * @param address
   */
  private void sendMessageToProcess(Message workMess, int address)
      throws RemoteException, NotBoundException {
    // 1]locate NodeInfo object
    NodeInfo[] nodeInfos = this.directory.listNodes();
    NodeInfo regNode = null;
    // System.out.println("NodeInfoLength = "+nodeInfos.length+"\n"+
    //        "Processing nodes:");
    for (int i = 0; i < nodeInfos.length; i++) {
      //  System.out.println("-->"+nodeInfos[i].toString()+" "+address);
      if (nodeInfos[i].getID() == address) {
        regNode = nodeInfos[i];
      }
    }

    // 2]Get remote registry
    Registry remoteRegistry = LocateRegistry.getRegistry(regNode.getIP(), regNode.getPort());

    // 3]Lookup and put data
    String nodeName = NODE_NAME_PREFIX + address;

    // set clock
    this.clock++; // increment clock
    workMess.setClock(clock);

    // message prepared
    this.log.logNode(
        "Sending message to processs " + address + "-->" + workMess.toString(),
        clock,
        this.nodeInfo.getID());
    NodeInterface nodeDirectory = (NodeInterface) remoteRegistry.lookup(nodeName);
    nodeDirectory.putMessage(workMess);
  }
예제 #2
0
  /** Method for terminated message spam. */
  private void sendTerminatedMessage() throws RemoteException, NotBoundException {
    Message messTerm = new Message();
    messTerm.setType(MessageType.WORK_TERMINATED);
    this.log.logNode("Sending termination message to all nodes.", clock, this.nodeInfo.getID());

    for (NodeInfo node : this.directory.listNodes()) {
      this.sendMessageToProcess(messTerm, node.getID());
    }
  }
예제 #3
0
 /** This method sends start token */
 private void sendStartToken() throws RemoteException, NotBoundException {
   if (this.directory.getNodeCount() > 1) {
     int neighbourID = this.getNeighbourID();
     Message mess = new Message();
     mess.setType(MessageType.TOKEN);
     mess.setColor(Color.WHITE);
     this.sendMessageToProcess(mess, neighbourID);
     this.log.logNode("Sending TOKEN.", clock, this.nodeInfo.getID());
   }
 }
예제 #4
0
  /**
   * Inserts message into queue
   *
   * @param message - message to insert
   * @throws RemoteException
   */
  @Override
  public synchronized void putMessage(Message message) throws RemoteException {
    Message messageTmp = new Message();
    messageTmp.setClock(message.getClock());
    messageTmp.setColor(message.getColor());
    messageTmp.setPayload(message.getPayload());
    messageTmp.setType(message.getType());

    this.messageQueue.add(message);
  }
예제 #5
0
  /**
   * Token processing & sending
   *
   * @param mess - message
   */
  private void processToken(Message mess) throws RemoteException, NotBoundException {
    Message outMess = new Message();
    outMess.setType(MessageType.TOKEN);
    this.log.logNode("Received message -> " + mess.toString(), clock, this.nodeInfo.getID());

    if (mess.getColor() == Color.BLACK) {
      // black token
      if (this.nodeInfo.getID() == 0) {
        // primary process
        this.log.logNode("BLACK node has been received.", clock, 0);
        this.startTokenSent = false;
      } else {
        outMess.setColor(Color.BLACK);
      }
    } else {
      // white token

      if (this.nodeInfo.getID() == 0) {
        // primary process --> received white node;all stops working
        this.log.logNode("Work has been terminated :).", clock, 0);
        sendTerminatedMessage();
        this.init();
      } else {

        // i am not the primary process
        if (this.myState == NodeState.PASSIVE) {
          // I don't have any work
          outMess.setColor(myColor);
        } else {
          // I have work
          outMess.setColor(Color.BLACK);
        }
      }
    }

    // get node count and send token if node count is bigger than one
    if (this.directory.getNodeCount() == 1) return;

    // send data
    if (this.nodeInfo.getID() != 0) {
      int neighbourID = getNeighbourID();
      this.sendMessageToProcess(outMess, neighbourID);
    }

    // reset my color
    this.myColor = Color.WHITE;
  }
예제 #6
0
  /** Queue process --> until it is not empty */
  private void processQueue() throws RemoteException, NotBoundException, InterruptedException {
    if (this.messageQueue.isEmpty()) {
      Thread.sleep(1000);
      return;
    }

    while (!this.messageQueue.isEmpty()) {
      Message mess = this.messageQueue.poll();
      MessageType type = mess.getType();
      // synchronize my logical time
      this.setNewClock(mess.getClock());

      switch (type) {
        case START:
          this.log.logNode("Starting work ...", -1, this.nodeInfo.getID());
          this.workAmount = new Random().nextInt(SLEEP_TIME_MODULE);
          this.log.logNode(
              "Generated work amount is " + this.workAmount + ".", clock, this.nodeInfo.getID());
          this.workStopAccepted = true;
          break;

        case GET_WORK: // some work with random time
          this.log.logNode(
              "Work has been received: " + mess.toString() + ".", clock, this.nodeInfo.getID());
          this.workAmount += Integer.parseInt(mess.getPayload());
          this.log.logNode(
              "New work amount is " + this.workAmount + ".", clock, this.nodeInfo.getID());
          break;

        case TOKEN:
          this.log.logNode(
              "Token has been received " + mess.toString(), clock, this.nodeInfo.getID());
          processToken(mess);
          break;

        case STOP:
          this.directory.logout(this.nodeInfo);
          this.log.logNode("Exiting", clock, this.nodeInfo.getID());
          System.exit(0);
          break;
        case WORK_TERMINATED:
          this.log.logNode("Work has been terminated :).", clock, this.nodeInfo.getID());
          this.init();
          break;
        default:
          // do nothing by default
          break;
      }
    }
  }
예제 #7
0
  /** Start random computing */
  private void startRandomWork() throws RemoteException, NotBoundException {
    try {
      // check if you have some work
      if (workAmount == 0) return;

      // simulate working
      Thread.sleep(WORK_AMOUNT_UNIT * 1000);

      // change variable with consumed work
      int oldWork = this.workAmount;
      this.workAmount -= WORK_AMOUNT_UNIT;
      if (this.workAmount < 0) {
        this.workAmount = 0;
      }

      // log it
      this.log.logNode(
          "Working :  " + oldWork + "->" + this.workAmount + ".", clock, this.nodeInfo.getID());

      ///////////////////////////////////////////////////////
      // if some work has been sent -> end it
      boolean sendWork = new Random().nextBoolean();
      if (workSent || sendWork) {
        // this.log.logNode("Work has been allready sent.", -1, this.nodeInfo.getID());
        return;
      }

      // send work to node with lower id
      if (this.directory.getNodeCount() > 1) {
        int randInd;

        // generate random number
        if (this.directory.getNodeCount() == 2) {
          randInd = this.getNeighbourID();
        } else {
          do {
            randInd = new Random().nextInt(this.directory.getNodeCount() - 1);
          } while (this.nodeInfo.getID() == randInd);
        }
        this.workSent = true;
        // send work
        int RandomWork = new Random().nextInt(SLEEP_TIME_MODULE);
        Message workMess =
            new Message(MessageType.GET_WORK, -1, Color.WHITE, Integer.toString(RandomWork));
        sendMessageToProcess(workMess, randInd);
        this.log.logNode(
            "Work has been sent to " + randInd + "->" + workMess.toString() + ".",
            clock,
            this.nodeInfo.getID());

        // change my color -> if you are sending to the host with lower id
        if (this.nodeInfo.getID() > randInd) {
          this.myColor = Color.BLACK;
          this.log.logNode(
              "Receiver ID was smaller than mine -> I become to be BLACK.",
              clock,
              this.nodeInfo.getID());
        }
      }

    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
  }