1 /* 2 * Hunt - A redis client library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.redis.RedisSlotBasedConnectionHandler; 13 14 import hunt.redis.RedisClusterConnectionHandler; 15 16 import hunt.redis.Exceptions; 17 import hunt.redis.HostAndPort; 18 import hunt.redis.Redis; 19 import hunt.redis.RedisPool; 20 import hunt.redis.RedisPoolOptions; 21 22 import hunt.text.Common; 23 24 import hunt.collection.List; 25 import hunt.collection.Set; 26 import hunt.util.pool; 27 28 29 class RedisSlotBasedConnectionHandler : RedisClusterConnectionHandler { 30 31 this(HostAndPort[] nodes, RedisPoolOptions poolConfig) { 32 super(nodes, poolConfig); 33 } 34 35 36 override 37 Redis getConnection() { 38 // In antirez's redis-rb-cluster implementation, 39 // getRandomConnection always return valid connection (able to 40 // ping-pong) 41 // or exception if all connections are invalid 42 43 List!(RedisPool) pools = cache.getShuffledNodesPool(); 44 45 foreach(RedisPool pool ; pools) { 46 Redis redis = null; 47 try { 48 redis = pool.borrow(); 49 50 if (redis is null) { 51 continue; 52 } 53 54 string result = redis.ping(); 55 56 if (result.equalsIgnoreCase("pong")) return redis; 57 58 redis.close(); 59 } catch (RedisException ex) { 60 if (redis !is null) { 61 redis.close(); 62 } 63 } 64 } 65 66 throw new RedisNoReachableClusterNodeException("No reachable node in cluster"); 67 } 68 69 override 70 Redis getConnectionFromSlot(int slot) { 71 RedisPool connectionPool = cache.getSlotPool(slot); 72 if (connectionPool !is null) { 73 // It can't guaranteed to get valid connection because of node 74 // assignment 75 return connectionPool.borrow(); 76 } else { 77 renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state 78 connectionPool = cache.getSlotPool(slot); 79 if (connectionPool !is null) { 80 return connectionPool.borrow(); 81 } else { 82 //no choice, fallback to new connection to random node 83 return getConnection(); 84 } 85 } 86 } 87 }