public void invokeAsynchronous(byte[] request, ReplyListener listener, int[] targets) { reqId = generateRequestId(TOMMessageType.UNORDERED_REQUEST); requestType = TOMMessageType.UNORDERED_REQUEST; replyQuorum = (int) Math.ceil( (getViewManager().getCurrentViewN() + getViewManager().getCurrentViewF()) / 2) + 1; this.replyListener = listener; if (this.getViewManager().getStaticConf().isTheTTP()) { requestType = TOMMessageType.STATUS_REPLY; try { sendMessageToTargets(request, reqId, targets); } catch (RuntimeException re) { if (re.getMessage().equals("Server not connected")) { TOMMessage tm = new TOMMessage( targets[0], 0, reqId, TOMUtil.getBytes(StatusReply.OFFLINE.toString()), 0, requestType); listener.replyReceived(tm); } } } else sendMessageToTargets(request, reqId, targets); }
/** * This is the method invoked by the client side communication system. * * @param reply The reply delivered by the client side communication system */ @Override public void replyReceived(TOMMessage reply) { canReceiveLock.lock(); if (reqId == -1) { // no message being expected Logger.println( "throwing out request: sender=" + reply.getSender() + " reqId=" + reply.getSequence()); canReceiveLock.unlock(); return; } int pos = getViewManager().getCurrentViewPos(reply.getSender()); if (pos < 0) { // ignore messages that don't come from replicas canReceiveLock.unlock(); return; } if (reply.getSequence() == reqId && reply.getReqType() == requestType) { if (replyListener != null) { replyListener.replyReceived(reply); canReceiveLock.unlock(); return; } Logger.println( "Receiving reply from " + reply.getSender() + " with reqId:" + reply.getSequence() + ". Putting on pos=" + pos); if (replies[pos] == null) { receivedReplies++; } replies[pos] = reply; // Compare the reply just received, to the others int sameContent = 1; for (int i = 0; i < replies.length; i++) { if (i != pos && replies[i] != null && (comparator.compare(replies[i].getContent(), reply.getContent()) == 0)) { sameContent++; if (sameContent >= replyQuorum) { response = extractor.extractResponse(replies, sameContent, pos); reqId = -1; this.sm.release(); // resumes the thread that is executing the "invoke" method break; } } } if (response == null) { if (requestType.equals(TOMMessageType.ORDERED_REQUEST)) { if (receivedReplies == getViewManager().getCurrentViewN()) { reqId = -1; this.sm.release(); // resumes the thread that is executing the "invoke" method } } else { // UNORDERED if (receivedReplies != sameContent) { reqId = -1; this.sm.release(); // resumes the thread that is executing the "invoke" method } } } } // Critical section ends here. The semaphore can be released canReceiveLock.unlock(); }