private void tryWithMutex(MutableAtomicValue<byte[]> result, MakeValue makeValue)
      throws Exception {
    long startMs = System.currentTimeMillis();
    int retryCount = 0;

    if (mutex.acquire(promotedToLock.getMaxLockTime(), promotedToLock.getMaxLockTimeUnit())) {
      try {
        boolean done = false;
        while (!done) {
          result.stats.incrementPromotedTries();
          if (tryOnce(result, makeValue)) {
            result.succeeded = true;
            done = true;
          } else {
            if (!promotedToLock
                .getRetryPolicy()
                .allowRetry(
                    retryCount++,
                    System.currentTimeMillis() - startMs,
                    RetryLoop.getDefaultRetrySleeper())) {
              done = true;
            }
          }
        }
      } finally {
        mutex.release();
      }
    }

    result.stats.setPromotedTimeMs(System.currentTimeMillis() - startMs);
  }
  private Map<String, String> queryExhibitors(Exhibitors localExhibitors) {
    Map<String, String> values = newValues();

    long start = System.currentTimeMillis();
    int retries = 0;
    boolean done = false;
    while (!done) {
      List<String> hostnames = Lists.newArrayList(localExhibitors.getHostnames());
      if (hostnames.size() == 0) {
        done = true;
      } else {
        String hostname = hostnames.get(random.nextInt(hostnames.size()));
        try {
          String encoded =
              restClient.getRaw(hostname, localExhibitors.getRestPort(), restUriPath, MIME_TYPE);
          values.putAll(decodeExhibitorList(encoded));
          done = true;
        } catch (Throwable e) {
          if (retryPolicy.allowRetry(
              retries++, System.currentTimeMillis() - start, RetryLoop.getDefaultRetrySleeper())) {
            log.warn("Couldn't get servers from Exhibitor. Retrying.", e);
          } else {
            log.error("Couldn't get servers from Exhibitor. Giving up.", e);
            done = true;
          }
        }
      }
    }

    return values;
  }
  private void tryOptimistic(MutableAtomicValue<byte[]> result, MakeValue makeValue)
      throws Exception {
    long startMs = System.currentTimeMillis();
    int retryCount = 0;

    boolean done = false;
    while (!done) {
      result.stats.incrementOptimisticTries();
      if (tryOnce(result, makeValue)) {
        result.succeeded = true;
        done = true;
      } else {
        if (!retryPolicy.allowRetry(
            retryCount++,
            System.currentTimeMillis() - startMs,
            RetryLoop.getDefaultRetrySleeper())) {
          done = true;
        }
      }
    }

    result.stats.setOptimisticTimeMs(System.currentTimeMillis() - startMs);
  }