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");
    }
  }