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.ShardedRedisPool;
13 
14 import hunt.redis.BinaryRedis;
15 import hunt.redis.BinaryShardedRedis;
16 import hunt.redis.Redis;
17 import hunt.redis.RedisShardInfo;
18 import hunt.redis.ShardedRedis;
19 import hunt.redis.ShardedRedisPool;
20 import hunt.redis.util.Hashing;
21 import hunt.redis.util.Pool;
22 
23 import hunt.collection.List;
24 
25 import hunt.pool.PooledObject;
26 import hunt.pool.PooledObjectFactory;
27 import hunt.pool.impl.DefaultPooledObject;
28 import hunt.pool.impl.GenericObjectPoolConfig;
29 
30 import hunt.Boolean;
31 
32 import std.regex;
33 alias Pattern = Regex!char;
34 
35 
36 class ShardedRedisPool : Pool!(ShardedRedis) {
37     this(GenericObjectPoolConfig poolConfig, List!(RedisShardInfo) shards) {
38         this(poolConfig, shards, Hashing.MURMUR_HASH);
39     }
40 
41     this(GenericObjectPoolConfig poolConfig, List!(RedisShardInfo) shards,
42             Hashing algo) {
43         this(poolConfig, shards, algo, Pattern.init);
44     }
45 
46     this(GenericObjectPoolConfig poolConfig, List!(RedisShardInfo) shards,
47             Pattern keyTagPattern) {
48         this(poolConfig, shards, Hashing.MURMUR_HASH, keyTagPattern);
49     }
50 
51     this(GenericObjectPoolConfig poolConfig, List!(RedisShardInfo) shards,
52             Hashing algo, Pattern keyTagPattern) {
53         super(poolConfig, new ShardedRedisFactory(shards, algo, keyTagPattern));
54     }
55 
56     override
57     ShardedRedis getResource() {
58         ShardedRedis jedis = super.getResource();
59         jedis.setDataSource(this);
60         return jedis;
61     }
62 
63     override
64     void returnBrokenResource(ShardedRedis resource) {
65         if (resource !is null) {
66             returnBrokenResourceObject(resource);
67         }
68     }
69 
70     override
71     void returnResource(ShardedRedis resource) {
72         if (resource !is null) {
73             resource.resetState();
74             returnResourceObject(resource);
75         }
76     }
77 }
78 
79 
80 /**
81  * PoolableObjectFactory custom impl.
82  */
83 private class ShardedRedisFactory : PooledObjectFactory!(ShardedRedis) {
84     private List!(RedisShardInfo) shards;
85     private Hashing algo;
86     private Pattern keyTagPattern;
87 
88     this(List!(RedisShardInfo) shards, Hashing algo, Pattern keyTagPattern) {
89         this.shards = shards;
90         this.algo = algo;
91         this.keyTagPattern = keyTagPattern;
92     }
93 
94     override
95     IPooledObject makeObject() {
96         ShardedRedis jedis = new ShardedRedis(shards, algo, keyTagPattern);
97         return new DefaultPooledObject!(ShardedRedis)(jedis);
98     }
99 
100     override
101     void destroyObject(IPooledObject pooledRedis) {
102         ShardedRedis shardedRedis = (cast(PooledObject!ShardedRedis)pooledRedis).getObject();
103         assert(shardedRedis !is null);
104         foreach(Redis jedis ; shardedRedis.getAllShards()) {
105             if (jedis.isConnected()) {
106                 try {
107                     try {
108                         jedis.quit();
109                     } catch (Exception e) {
110 
111                     }
112                     jedis.disconnect();
113                 } catch (Exception e) {
114 
115                 }
116             }
117         }
118     }
119 
120     override
121     bool validateObject(IPooledObject pooledRedis) {
122         try {
123             ShardedRedis jedis = (cast(PooledObject!ShardedRedis)pooledRedis).getObject();
124             assert(jedis !is null);
125             
126             foreach(Redis shard ; jedis.getAllShards()) {
127                 if (shard.ping() != "PONG") {
128                     return false;
129                 }
130             }
131             return true;
132         } catch (Exception ex) {
133             return false;
134         }
135     }
136 
137     override
138     void activateObject(IPooledObject p) {
139 
140     }
141 
142     override
143     void passivateObject(IPooledObject p) {
144 
145     }
146 }