private int getDownInstanceRestartMs(InstanceConfig config) {
    EncodedConfigParser parser =
        new EncodedConfigParser(
            exhibitor.getConfigManager().getConfig().getString(StringConfigs.ZOO_CFG_EXTRA));
    int tickTime = parseInt(parser.getValues().get("tickTime"));
    int initLimit = parseInt(parser.getValues().get("initLimit"));
    int syncLimit = parseInt(parser.getValues().get("syncLimit"));

    if ((tickTime > 0) && ((initLimit > 0) || (syncLimit > 0))) {
      return 2
          * tickTime
          * Math.max(initLimit, syncLimit); // ZK should sync or fail within the initLimit/syncLimit
    }

    return (config.getInt(IntConfigs.CHECK_MS) * DOWN_RECHECK_FACTOR);
  }
  @VisibleForTesting
  void doWork() throws Exception {
    InstanceConfig config = exhibitor.getConfigManager().getConfig();
    InstanceState instanceState =
        new InstanceState(
            new ServerList(config.getString(StringConfigs.SERVERS_SPEC)),
            new Checker(exhibitor).calculateState(),
            new RestartSignificantConfig(config));

    exhibitor.getConfigManager().checkRollingConfig(instanceState);

    InstanceState localCurrentInstanceState = currentInstanceState.get();
    if (instanceState.equals(localCurrentInstanceState)) {
      if ((localCurrentInstanceState.getState() == InstanceStateTypes.DOWN)
          || (localCurrentInstanceState.getState() == InstanceStateTypes.NOT_SERVING)) {
        if (!exhibitor.getConfigManager().isRolling()) {
          long elapsedMs = System.currentTimeMillis() - localCurrentInstanceState.getTimestampMs();
          int downInstanceRestartMs = getDownInstanceRestartMs(config);
          if (elapsedMs > downInstanceRestartMs) {
            exhibitor
                .getLog()
                .add(
                    ActivityLog.Type.INFO,
                    "Restarting down/not-serving ZooKeeper after " + elapsedMs + " ms pause");
            restartZooKeeper(localCurrentInstanceState);
          } else {
            exhibitor
                .getLog()
                .add(
                    ActivityLog.Type.INFO,
                    "ZooKeeper down/not-serving waiting "
                        + elapsedMs
                        + " of "
                        + downInstanceRestartMs
                        + " ms before restarting");
          }
        }
      }
    } else {
      boolean serverListChange =
          (localCurrentInstanceState != null)
              && !localCurrentInstanceState.getServerList().equals(instanceState.getServerList());
      boolean configChange =
          (localCurrentInstanceState != null)
              && !localCurrentInstanceState
                  .getCurrentConfig()
                  .equals(instanceState.getCurrentConfig());
      currentInstanceState.set(instanceState);

      exhibitor
          .getLog()
          .add(ActivityLog.Type.INFO, "State: " + instanceState.getState().getDescription());

      if (serverListChange) {
        exhibitor.getLog().add(ActivityLog.Type.INFO, "Server list has changed");
        restartZooKeeper(localCurrentInstanceState);
      } else if (configChange) {
        exhibitor
            .getLog()
            .add(ActivityLog.Type.INFO, "ZooKeeper related configuration has changed");
        restartZooKeeper(localCurrentInstanceState);
      } else {
        switch (instanceState.getState()) {
          case DOWN:
            {
              restartZooKeeper(localCurrentInstanceState);
              break;
            }

          default:
            {
              // nop
              break;
            }
        }
      }
    }
  }