content: package redis.clients.jedis;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
  
  import redis.clients.jedis.exceptions.JedisConnectionException;
  
  public abstract class JedisClusterConnectionHandler {
    protected final JedisClusterInfoCache cache;
  
    abstract Jedis getConnection();
  
    abstract Jedis getConnectionFromSlot(int slot);
  
    public Jedis getConnectionFromNode(HostAndPort node) {
      cache.setNodeIfNotExist(node);
      return cache.getNode(JedisClusterInfoCache.getNodeKey(node)).getResource();
    }
  
    public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
        final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
      this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout);
      initializeSlotsCache(nodes, poolConfig);
    }
  
    public Map<String, JedisPool> getNodes() {
      return cache.getNodes();
    }
  
    private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
      for (HostAndPort hostAndPort : startNodes) {
        Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
        try {
          cache.discoverClusterNodesAndSlots(jedis);
          break;
        } catch (JedisConnectionException e) {
          // try next nodes
        } finally {
          if (jedis != null) {
            jedis.close();
          }
        }
      }
  
      for (HostAndPort node : startNodes) {
        cache.setNodeIfNotExist(node);
      }
    }
  
    public void renewSlotCache() {
      for (JedisPool jp : getShuffledNodesPool()) {
        Jedis jedis = null;
        try {
          jedis = jp.getResource();
          cache.discoverClusterSlots(jedis);
          break;
        } catch (JedisConnectionException e) {
          // try next nodes
        } finally {
          if (jedis != null) {
            jedis.close();
          }
        }
      }
    }
  
    public void renewSlotCache(Jedis jedis) {
      try {
        cache.discoverClusterSlots(jedis);
      } catch (JedisConnectionException e) {
        renewSlotCache();
      }
    }
  
    protected List<JedisPool> getShuffledNodesPool() {
      List<JedisPool> pools = new ArrayList<JedisPool>();
      pools.addAll(cache.getNodes().values());
      Collections.shuffle(pools);
      return pools;
    }
      public JedisPool getJedisPoolFromSlot(int slot){
          return cache.getSlotPool(slot);
      }
  
      private Jedis getRunningJedis(){
          Jedis jedis = null;
          for (JedisPool jp : cache.getNodes().values()) {
              try {
                  jedis = jp.getResource();
                  if (jedis.ping().equalsIgnoreCase("PONG")) {
                      return jedis;
                  }
              } catch (Exception e) {
                  //ignore
              }
          }
          return jedis;
      }
  }
  