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); }
public byte[] getCurrentStateHash() { byte[] currentState = getSnapshot(); byte[] currentStateHash = TOMUtil.computeHash(currentState); System.out.println( "--- State size: " + currentState.length + " Current state Hash: " + Arrays.toString(currentStateHash)); return currentStateHash; }
/** * This method sends a request to the replicas, and returns the related reply. If the servers take * more than invokeTimeout seconds the method returns null. This method is thread-safe. * * @param request Request to be sent * @param reqType TOM_NORMAL_REQUESTS for service requests, and other for reconfig requests. * @return The reply from the replicas related to request */ public byte[] invoke(byte[] request, TOMMessageType reqType) { canSendLock.lock(); // Clean all statefull data to prepare for receiving next replies Arrays.fill(replies, null); receivedReplies = 0; response = null; replyListener = null; replyQuorum = (int) Math.ceil( (getViewManager().getCurrentViewN() + getViewManager().getCurrentViewF()) / 2) + 1; // Send the request to the replicas, and get its ID reqId = generateRequestId(reqType); requestType = reqType; TOMulticast(request, reqId, reqType); Logger.println("Sending request (" + reqType + ") with reqId=" + reqId); Logger.println("Expected number of matching replies: " + replyQuorum); // This instruction blocks the thread, until a response is obtained. // The thread will be unblocked when the method replyReceived is invoked // by the client side communication system try { if (!this.sm.tryAcquire(invokeTimeout, TimeUnit.SECONDS)) { Logger.println("###################TIMEOUT#######################"); Logger.println("Reply timeout for reqId=" + reqId); canSendLock.unlock(); System.out.print(getProcessId() + " // " + reqId + " // TIMEOUT // "); System.out.println("Replies received: " + receivedReplies); return null; } } catch (InterruptedException ex) { } Logger.println("Response extracted = " + response); byte[] ret = null; if (response == null) { // the response can be null if n-f replies are received but there isn't // a replyQuorum of matching replies Logger.println("Received n-f replies and no response could be extracted."); canSendLock.unlock(); if (reqType == TOMMessageType.UNORDERED_REQUEST) { // invoke the operation again, whitout the read-only flag Logger.println("###################RETRY#######################"); return invokeOrdered(request); } else { throw new RuntimeException("Received n-f replies without f+1 of them matching."); } } else { // normal operation // ******* EDUARDO BEGIN **************// if (reqType == TOMMessageType.ORDERED_REQUEST) { // Reply to a normal request! if (response.getViewID() == getViewManager().getCurrentViewId()) { ret = response.getContent(); // return the response } else { // if(response.getViewID() > getViewManager().getCurrentViewId()) // updated view received reconfigureTo((View) TOMUtil.getObject(response.getContent())); canSendLock.unlock(); return invoke(request, reqType); } } else { if (response.getViewID() > getViewManager().getCurrentViewId()) { // Reply to a reconfigure request! Logger.println("Reconfiguration request' reply received!"); Object r = TOMUtil.getObject(response.getContent()); if (r instanceof View) { // did not executed the request because it is using an outdated view reconfigureTo((View) r); canSendLock.unlock(); return invoke(request, reqType); } else { // reconfiguration executed! reconfigureTo(((ReconfigureReply) r).getView()); ret = response.getContent(); } } else { // Reply to readonly request ret = response.getContent(); } } } // ******* EDUARDO END **************// canSendLock.unlock(); return ret; }