@Override
 public List<String> getOnlineShardServers(boolean useCache, String cluster) {
   if (useCache) {
     synchronized (_onlineShardsNodes) {
       Map<String, List<String>> map = _onlineShardsNodes.get();
       if (map != null) {
         List<String> shards = map.get(cluster);
         if (shards != null) {
           return shards;
         }
       } else {
         _onlineShardsNodes.set(new ConcurrentHashMap<String, List<String>>());
         watchForOnlineShardNodes(cluster);
       }
     }
   }
   LOG.info("trace getOnlineShardServers");
   try {
     return _zk.getChildren(
         ZookeeperPathConstants.getClustersPath() + "/" + cluster + "/online/shard-nodes", false);
   } catch (KeeperException e) {
     throw new RuntimeException(e);
   } catch (InterruptedException e) {
     throw new RuntimeException(e);
   }
 }
 @Override
 public List<String> getClusterList() {
   LOG.info("trace getClusterList");
   try {
     return _zk.getChildren(ZookeeperPathConstants.getClustersPath(), false);
   } catch (KeeperException e) {
     throw new RuntimeException(e);
   } catch (InterruptedException e) {
     throw new RuntimeException(e);
   }
 }
 @Override
 public List<String> getShardServerList(String cluster) {
   LOG.debug("trace getShardServerList");
   try {
     return _zk.getChildren(
         ZookeeperPathConstants.getClustersPath() + "/" + cluster + "/shard-nodes", false);
   } catch (KeeperException e) {
     throw new RuntimeException(e);
   } catch (InterruptedException e) {
     throw new RuntimeException(e);
   }
 }
 private void watchForClusters() {
   clusterWatch =
       new WatchChildren(_zk, ZookeeperPathConstants.getClustersPath()).watch(new Clusters());
 }