/** * 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); }
/** 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()); } }
/** 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()); } }
/** * 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); }
/** * 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; }
/** 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; } } }
/** 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(); } }