@VisibleForTesting
  protected void restartZooKeeper(InstanceState currentInstanceState) throws Exception {
    if (currentInstanceState != null) {
      currentInstanceState.updateTimestampMs();
    }
    if (!exhibitor.getControlPanelValues().isSet(ControlPanelTypes.RESTARTS)) {
      exhibitor
          .getLog()
          .add(ActivityLog.Type.INFO, "Restart of ZooKeeper skipped due to control panel setting");
      return;
    }

    exhibitor.getActivityQueue().add(QueueGroups.MAIN, new KillRunningInstance(exhibitor, true));
  }
  public MonitorRunningInstance(Exhibitor exhibitor) {
    this.exhibitor = exhibitor;
    Activity activity =
        new Activity() {
          @Override
          public void completed(boolean wasSuccessful) {
            // NOP
          }

          @Override
          public Boolean call() throws Exception {
            doWork();
            return true;
          }
        };

    repeatingActivity =
        new RepeatingActivity(
            exhibitor.getLog(),
            exhibitor.getActivityQueue(),
            QueueGroups.MAIN,
            activity,
            exhibitor.getConfigManager().getConfig().getInt(IntConfigs.CHECK_MS));
  }
  @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;
            }
        }
      }
    }
  }