private synchronized void checkTimeouts() throws Exception {
   long elapsed = System.currentTimeMillis() - connectionStartMs;
   if (elapsed >= Math.min(sessionTimeoutMs, connectionTimeoutMs)) {
     if (zooKeeper.hasNewConnectionString()) {
       handleNewConnectionString();
     } else if (elapsed > sessionTimeoutMs) {
       if (!Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES)) {
         log.warn(
             String.format(
                 "Connection attempt unsuccessful after %d (greater than session timeout of %d). Resetting connection and trying again with a new connection.",
                 elapsed, sessionTimeoutMs));
       }
       reset();
     } else {
       KeeperException.ConnectionLossException connectionLossException =
           new KeeperException.ConnectionLossException();
       if (!Boolean.getBoolean(DebugUtils.PROPERTY_DONT_LOG_CONNECTION_ISSUES)) {
         log.error(
             String.format(
                 "Connection timed out for connection string (%s) and timeout (%d) / elapsed (%d)",
                 zooKeeper.getConnectionString(), connectionTimeoutMs, elapsed),
             connectionLossException);
       }
       tracer.get().addCount("connections-timed-out", 1);
       throw connectionLossException;
     }
   }
 }
  private void handleExpiredSession() {
    log.warn("Session expired event received");
    tracer.get().addCount("session-expired", 1);

    try {
      reset();
    } catch (Exception e) {
      queueBackgroundException(e);
    }
  }
  private void handleNewConnectionString() {
    log.info("Connection string changed");
    tracer.get().addCount("connection-string-changed", 1);

    try {
      reset();
    } catch (Exception e) {
      queueBackgroundException(e);
    }
  }
 void start() throws Exception {
   log.debug("Starting");
   ensembleProvider.start();
   reset();
 }