示例#1
0
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    byte[] serReq = new byte[in.readInt()];
    in.readFully(serReq);

    request = TOMMessage.bytesToMessage(serReq);
    request.serializedMessage = serReq;

    boolean signed = in.readBoolean();

    if (signed) {

      byte[] serReqSign = new byte[in.readInt()];
      in.readFully(serReqSign);
      request.serializedMessageSignature = serReqSign;
    }
  }
示例#2
0
  /**
   * 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();
  }
示例#3
0
  /**
   * 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;
  }