public synchronized RspList<Object> getResponseList() throws Exception {
   long expectedEndTime = timeService.expectedEndTime(timeout, MILLISECONDS);
   long waitingTime;
   while (expectedResponses > 0
       && retval == null
       && (waitingTime = timeService.remainingTime(expectedEndTime, MILLISECONDS)) > 0) {
     try {
       this.wait(waitingTime);
     } catch (InterruptedException e) {
       // reset interruption flag
       Thread.currentThread().interrupt();
       expectedResponses = -1;
     }
   }
   // Now we either have the response we need or aren't expecting any more responses - or have
   // run out of time.
   if (retval != null) return retval;
   else if (exception != null) throw exception;
   else if (expectedResponses == 0)
     throw new RpcException(
         format(
             "No more valid responses.  Received invalid responses from all of %s",
             futures.values()));
   else
     throw new TimeoutException(
         format(
             "Timed out waiting for %s for valid responses from any of %s.",
             Util.prettyPrintTime(timeout), futures.values()));
 }
  private static RspList<Object> processCalls(
      Map<Address, ReplicableCommand> commands,
      long timeout,
      ResponseMode mode,
      Marshaller marshaller,
      CommandAwareRpcDispatcher card,
      boolean oob,
      boolean ignoreLeavers)
      throws Exception {
    if (trace) log.tracef("Replication task sending %s with response mode %s", commands, mode);

    if (commands.isEmpty()) return new RspList<>();

    RequestOptions opts = new RequestOptions(mode, timeout);
    // opts.setExclusionList(card.getChannel().getAddress());

    Map<Address, Future<Object>> futures = new HashMap<Address, Future<Object>>(commands.size());
    RspList<Object> retval = new RspList<>();

    for (Map.Entry<Address, ReplicableCommand> cmd : commands.entrySet()) {
      Buffer buf = marshallCall(marshaller, cmd.getValue());
      Address dest = cmd.getKey();
      boolean rsvp = isRsvpCommand(cmd.getValue());
      futures.put(
          dest,
          card.sendMessageWithFuture(constructMessage(buf, dest, oob, mode, rsvp, false), opts));
    }

    // a get() on each future will block till that call completes.
    TimeService timeService = card.timeService;
    long waitTime = timeService.expectedEndTime(timeout, MILLISECONDS);
    for (Map.Entry<Address, Future<Object>> entry : futures.entrySet()) {
      Address target = entry.getKey();
      try {
        retval.addRsp(
            target,
            entry.getValue().get(timeService.remainingTime(waitTime, MILLISECONDS), MILLISECONDS));
      } catch (java.util.concurrent.TimeoutException te) {
        throw new TimeoutException(
            formatString(
                "Timed out after %s waiting for a response from %s",
                prettyPrintTime(timeout), target));
      } catch (ExecutionException e) {
        if (ignoreLeavers && e.getCause() instanceof SuspectedException) {
          retval.addRsp(target, new ExceptionResponse((SuspectedException) e.getCause()));
        } else {
          throw wrapThrowableInException(e.getCause());
        }
      }
    }
    return retval;
  }
 private void waitForView(int viewId, long timeout) throws InterruptedException {
   if (this.viewId < viewId) {
     log.tracef(
         "Received a cache topology command with a higher view id: %s, our view id is %s",
         viewId, this.viewId);
   }
   long endTime = timeService.expectedEndTime(timeout, TimeUnit.MILLISECONDS);
   synchronized (viewUpdateLock) {
     while (this.viewId < viewId && !timeService.isTimeExpired(endTime)) {
       viewUpdateLock.wait(1000);
     }
   }
   if (this.viewId < viewId) {
     throw new TimeoutException("Timed out waiting for view " + viewId);
   }
 }
  private void shutDownGracefully() {
    if (log.isDebugEnabled())
      log.debugf(
          "Wait for on-going transactions to finish for %s.",
          Util.prettyPrintTime(
              configuration.transaction().cacheStopTimeout(), TimeUnit.MILLISECONDS));
    long failTime =
        timeService.expectedEndTime(
            configuration.transaction().cacheStopTimeout(), TimeUnit.MILLISECONDS);
    boolean txsOnGoing = areTxsOnGoing();
    while (txsOnGoing && !timeService.isTimeExpired(failTime)) {
      try {
        Thread.sleep(30);
        txsOnGoing = areTxsOnGoing();
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        if (clustered) {
          log.debugf(
              "Interrupted waiting for on-going transactions to finish. %s local transactions and %s remote transactions",
              localTransactions.size(), remoteTransactions.size());
        } else {
          log.debugf(
              "Interrupted waiting for %s on-going transactions to finish.",
              localTransactions.size());
        }
      }
    }

    if (txsOnGoing) {
      log.unfinishedTransactionsRemain(
          localTransactions == null ? 0 : localTransactions.size(),
          remoteTransactions == null ? 0 : remoteTransactions.size());
    } else {
      log.debug("All transactions terminated");
    }
  }