@Override
  public Boolean call() throws Exception {

    long timeoutMillis = 5000;

    try {
      getServersFile();
      getZkRunning();

      while (true) {
        while (!restartQueue.isEmpty()) {
          LOG.debug("Restart queue size [" + restartQueue.size() + "]");
          RestartHandler handler = restartQueue.poll();
          Future<ScriptContext> runner = pool.submit(handler);
          ScriptContext scriptContext = runner.get(); // blocking call
          if (scriptContext.getExitCode() != 0) restartQueue.add(handler);
        }

        try {
          Thread.sleep(timeoutMillis);
        } catch (InterruptedException e) {
        }
      }

    } catch (Exception e) {
      e.printStackTrace();
      LOG.error(e);
      pool.shutdown();
      throw e;
    }
  }
  @Test(timeout = 1500l)
  public void testConditionWaitsForSignalOtherClient() throws Exception {
    final Lock firstLock = new ReentrantZkLock(baseLockPath, zkSessionManager);
    final Condition firstCondition = firstLock.newCondition();

    firstLock.lock();
    // fire off a thread that will signal the main process thread
    Future<Void> errorFuture =
        testService.submit(
            new Callable<Void>() {
              @Override
              public Void call() throws Exception {
                final Lock otherClientLock;
                ZooKeeper newZk = newZooKeeper();
                try {
                  otherClientLock =
                      new ReentrantZkLock(baseLockPath, new BaseZkSessionManager(newZk));
                  final Condition otherClientCondition = otherClientLock.newCondition();
                  otherClientLock.lock();
                  System.out.println("Lock acquired on second thread");
                  try {
                    otherClientCondition.signal();
                    System.out.println("Lock signalled on second thread");
                  } finally {
                    System.out.println("Lock released on second thread");
                    otherClientLock.unlock();
                  }
                  return null;
                } finally {
                  closeZooKeeper(newZk);
                }
              }
            });

    // wait for signal notification
    System.out.println("First thread waiting for notification");
    firstCondition.await();
    System.out.println("First thread has been notified");
    firstLock.unlock();
    errorFuture.get();
  }