private void getDeadMembersFromCoordinator() {
   if (!deadMembersKnown) {
     try {
       DistributedReplicantManager drm = partition.getDistributedReplicantManager();
       List<ClusterNode> nodes = drm.lookupReplicantsNodes(getServiceHAName());
       ClusterNode coord = (nodes != null && nodes.size() > 0 ? nodes.get(0) : null);
       if (coord != null && coord.equals(partition.getClusterNode()) == false) {
         Object rsp =
             partition.callMethodOnNode(
                 getServiceHAName(), "getDiscrepancies", NULL_ARGS, NULL_TYPES, 60000, coord);
         if (rsp instanceof RemoteDiscrepancies) {
           handleRemoteDiscrepancies((RemoteDiscrepancies) rsp);
           deadMembersKnown = true;
         } else {
           log.error("No valid response from coordinator: " + rsp);
         }
       }
     } catch (Throwable e) {
       if (e instanceof Error) {
         throw (Error) e;
       }
       log.error("Caught exception pulling dead member records from coordinator", e);
     }
   }
 }
 /**
  * Takes a set of discrepancies provided by another node and adds any missing entries to our
  * discrepancy set, *after* adjusting the TimestampDiscrepancy objects to incorporate our
  * discrepancy with the node that provided the set.
  */
 private void convertRemoteDiscrepanciesToLocalTime(
     Map<Server, TimestampDiscrepancy> remoteDiscrepancies,
     TimestampDiscrepancy senderDiscrepancy) {
   for (Map.Entry<Server, TimestampDiscrepancy> entry : remoteDiscrepancies.entrySet()) {
     Server key = entry.getKey();
     if (discrepancies.get(key) == null) {
       // A node we didn't know about
       discrepancies.put(
           new Server(key, senderDiscrepancy),
           new TimestampDiscrepancy(entry.getValue(), senderDiscrepancy));
       ClusterNode node = key.getNode();
       nodesByName.put(node.getName(), node);
     }
   }
 }
 @Override
 public int hashCode() {
   return node.hashCode();
 }
  private synchronized void statusCheck() {
    if (statusCheckRequired
        || (System.currentTimeMillis() - lastStatusCheck > minStatusCheckFrequency)) {
      try {
        long requestSent = System.currentTimeMillis();
        @SuppressWarnings("unchecked")
        List rsps =
            partition.callMethodOnCluster(
                getServiceHAName(), "getLocalTimestamp", NULL_ARGS, NULL_TYPES, true);
        long responseReceived = System.currentTimeMillis();
        long mcastTime = responseReceived - requestSent;

        Map<ClusterNode, TimestampDiscrepancy> rspBySender =
            new HashMap<ClusterNode, TimestampDiscrepancy>();
        if (rsps != null) {
          for (Object rsp : rsps) {
            if (rsp instanceof TimestampResponse) {
              TimestampResponse tr = (TimestampResponse) rsp;
              rspBySender.put(
                  tr.getResponder(),
                  new TimestampDiscrepancy(tr.getTimestamp(), requestSent, responseReceived));
            } else if (rsp != null) {
              log.warn("Unknown status check response " + rsp);
            }
          }
        }

        if (mcastTime > 250) {
          // Multicasting the RPC introduced a high possible error;
          // see if multiple unicast is better
          List<ClusterNode> nodes =
              partition.getDistributedReplicantManager().lookupReplicantsNodes(getServiceHAName());
          for (ClusterNode node : nodes) {
            if (node.equals(this.partition.getClusterNode())) {
              continue;
            }

            try {
              long singleRequestSent = System.currentTimeMillis();
              Object rsp =
                  partition.callMethodOnNode(
                      getServiceHAName(),
                      "getLocalTimestamp",
                      NULL_ARGS,
                      NULL_TYPES,
                      mcastTime,
                      node);
              long singleResponseReceived = System.currentTimeMillis();
              long elapsed = singleResponseReceived - singleRequestSent;
              if (elapsed < mcastTime) // better result than multicast
              {
                if (rsp instanceof TimestampResponse) {
                  TimestampResponse tr = (TimestampResponse) rsp;
                  rspBySender.put(
                      tr.getResponder(),
                      new TimestampDiscrepancy(
                          tr.getTimestamp(), singleRequestSent, singleResponseReceived));
                } else if (rsp != null) {
                  log.warn("Unknown status check response " + rsp);
                }
              }
            } catch (Throwable e) {
              if (e instanceof Error) {
                throw (Error) e;
              }
              log.error("Caught exception requesting timestamp from node " + node, e);
            }
          }
        }

        synchronized (discrepancies) {
          synchronized (liveServers) {
            for (Map.Entry<ClusterNode, TimestampDiscrepancy> entry : rspBySender.entrySet()) {
              Server s = new Server(entry.getKey());
              TimestampDiscrepancy latest = entry.getValue();
              TimestampDiscrepancy existing = discrepancies.get(s);
              if (existing == null
                  || latest.getDiscrepancyRange() <= existing.getDiscrepancyRange()
                  || liveServers.contains(s) == false) {
                updateTimestampDiscrepancy(s, latest, true);
              } else {
                // We already have an entry for this live server with a
                // narrower range that we'd prefer to keep
                // If the new entry doesn't fit within the parameters
                // of the old, we have to replace the old
                if (existing.getMinDiscrepancy() < latest.getMinDiscrepancy()
                    || existing.getMaxDiscrepancy() > latest.getMaxDiscrepancy()) {
                  updateTimestampDiscrepancy(s, latest, true);
                } else {
                  // Re-store existing, but with the new key
                  updateTimestampDiscrepancy(s, existing, true);
                }
              }
            }
          }
        }

        statusCheckRequired = false;
        lastStatusCheck = System.currentTimeMillis();
      } catch (Exception e) {
        log.error("Caught exception in status check", e);
      }
    }

    getDeadMembersFromCoordinator();
  }