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.RedisFactory; 13 14 import hunt.pool.PooledObject; 15 import hunt.pool.PooledObjectFactory; 16 import hunt.pool.impl.DefaultPooledObject; 17 18 import hunt.redis.BinaryRedis; 19 import hunt.redis.Exceptions; 20 import hunt.redis.HostAndPort; 21 import hunt.redis.Redis; 22 import hunt.redis.util.RedisURIHelper; 23 24 import hunt.logging.ConsoleLogger; 25 import hunt.net.util.HttpURI; 26 27 import std.format; 28 import std.range; 29 30 /** 31 * PoolableObjectFactory custom impl. 32 */ 33 class RedisFactory : PooledObjectFactory!(Redis) { 34 private HostAndPort hostAndPort; 35 private int connectionTimeout; 36 private int soTimeout; 37 private string password; 38 private int database; 39 private string clientName; 40 private bool ssl; 41 // private SSLSocketFactory sslSocketFactory; 42 // private SSLParameters sslParameters; 43 // private HostnameVerifier hostnameVerifier; 44 45 this(string host, int port, int connectionTimeout, int soTimeout, 46 string password, int database, string clientName) { 47 this.hostAndPort = new HostAndPort(host, port); 48 this.connectionTimeout = connectionTimeout; 49 this.soTimeout = soTimeout; 50 this.password = password; 51 this.database = database; 52 this.clientName = clientName; 53 this.ssl = false; 54 } 55 56 this(HttpURI uri, int connectionTimeout, int soTimeout, string clientName) { 57 if (!RedisURIHelper.isValid(uri)) { 58 throw new InvalidURIException(format( 59 "Cannot open Redis connection due invalid HttpURI. %s", uri.toString())); 60 } 61 62 this.hostAndPort = new HostAndPort(uri.getHost(), uri.getPort()); 63 this.connectionTimeout = connectionTimeout; 64 this.soTimeout = soTimeout; 65 this.password = RedisURIHelper.getPassword(uri); 66 this.database = RedisURIHelper.getDBIndex(uri); 67 this.clientName = clientName; 68 this.ssl = false; //RedisURIHelper.isRedisSSLScheme(uri); 69 } 70 71 void setHostAndPort(HostAndPort hostAndPort) { 72 this.hostAndPort = hostAndPort; 73 } 74 75 void activateObject(IPooledObject pooledRedis) { 76 Redis redis = (cast(PooledObject!Redis)pooledRedis).getObject(); 77 if (redis.getDB() != database) { 78 redis.select(database); 79 } 80 } 81 82 void destroyObject(IPooledObject pooledRedis) { 83 Redis redis = (cast(PooledObject!Redis)pooledRedis).getObject(); 84 if (redis.isConnected()) { 85 try { 86 try { 87 redis.quit(); 88 } catch (Exception e) { 89 } 90 redis.disconnect(); 91 } catch (Exception e) { 92 93 } 94 } 95 96 } 97 98 IPooledObject makeObject() { 99 HostAndPort hostAndPort = this.hostAndPort; 100 101 version(HUNT_REDIS_DEBUG) infof("%s", hostAndPort.toString()); 102 Redis redis = new Redis(hostAndPort.getHost(), hostAndPort.getPort(), 103 connectionTimeout, soTimeout, ssl); 104 105 try { 106 redis.connect(); 107 108 if (!password.empty) { 109 redis.auth(password); 110 } 111 112 if (database != 0) { 113 redis.select(database); 114 } 115 if (clientName !is null) { 116 redis.clientSetname(clientName); 117 } 118 } catch (RedisException je) { 119 debug warning(je.msg); 120 version(HUNT_DEBUG) warning(je); 121 redis.close(); 122 throw je; 123 } 124 125 return new DefaultPooledObject!(Redis)(redis); 126 127 } 128 129 void passivateObject(IPooledObject pooledRedis) { 130 // TODO maybe should select db 0? Not sure right now. 131 } 132 133 bool validateObject(IPooledObject pooledRedis) { 134 BinaryRedis redis = cast(BinaryRedis)(cast(PooledObject!Redis)pooledRedis).getObject(); 135 try { 136 HostAndPort hostAndPort = this.hostAndPort; 137 138 string connectionHost = redis.getClient().getHost(); 139 int connectionPort = redis.getClient().getPort(); 140 141 return hostAndPort.getHost() == connectionHost && hostAndPort.getPort() == connectionPort 142 && redis.isConnected() && redis.ping() == "PONG"; 143 } catch (Exception e) { 144 return false; 145 } 146 } 147 }