Skip to content

Commit f062f7d

Browse files
Merge pull request #5 from pearlshare/master
Fix to correctly resolve with client on pool factory
2 parents e4f4530 + 4a9c024 commit f062f7d

File tree

6 files changed

+344
-449
lines changed

6 files changed

+344
-449
lines changed

lib/redis_cache.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
"use strict";
2-
31
const RedisStore = require("./redis_store");
42

53
const debug = require("debug")("simpleRedisCache");
64

7-
function RedisCache (name, redisOptions, poolOptions) {
5+
var RedisCache = module.exports = function (name, redisOptions, poolOptions) {
86

97
this.name = name;
108
this.redisOptions = redisOptions;
119
this.poolOptions = poolOptions;
12-
13-
try {
14-
this.store = new RedisStore(name, redisOptions, poolOptions);
15-
debug("Success in connecting to Redis", redisOptions);
16-
} catch (e) {
17-
debug("Failed in connecting to Redis", redisOptions);
18-
}
19-
}
10+
this.store = new RedisStore(name, redisOptions, poolOptions);
11+
};
2012

2113
RedisCache.prototype.set = function (key, value, ttlInSeconds) {
2214
if (!this.store || ttlInSeconds === 0) return Promise.resolve(value);
@@ -60,5 +52,3 @@ RedisCache.prototype.wrap = function (key, promise, ttlInSeconds) {
6052
}
6153
});
6254
};
63-
64-
module.exports = RedisCache;

lib/redis_pool.js

Lines changed: 86 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
"use strict";
2-
31
const genericPool = require("generic-pool");
42
const redis = require("./redis");
53

64
const debug = require("debug")("simpleRedisPool");
75

8-
function RedisPool (name, redisOptions, poolOptions) {
6+
var RedisPool = module.exports = function (name, redisOptions, poolOptions) {
97

108
this.name = name;
9+
this.redisOptions = redisOptions;
10+
this.poolOptions = poolOptions;
1111
this._redisDb = redisOptions.db || 0;
12-
let _pool = null;
1312

1413
const factory = {
1514
create: () => {
@@ -18,23 +17,17 @@ function RedisPool (name, redisOptions, poolOptions) {
1817
const client = redis.createClient(redisOptions);
1918

2019
if (["undefined", null, ""].indexOf(this._redisDb) !== -1) {
21-
debug("Selected Redis DB: ", this._redisDb);
2220
debug("Selected Redis DB: ", this._redisDb);
2321
client.select(this._redisDb);
2422
}
2523

26-
// Handle client connection errors.
27-
client.on("error", err => {
28-
debug("Redis pool: ", name, err);
29-
reject(err);
30-
});
31-
3224
// Register the authentication password if needed.
3325
if (redisOptions.auth_pass) {
3426
client.auth(redisOptions.auth_pass);
3527
}
3628

37-
resolve(client);
29+
client.on("error", err => reject(err));
30+
client.on("connect", () => resolve(client));
3831
});
3932
},
4033
destroy: (client) => {
@@ -43,7 +36,7 @@ function RedisPool (name, redisOptions, poolOptions) {
4336
try {
4437
// Flush when closing.
4538
client.end(true);
46-
debug("Checking pool info after client destroyed. Available count : %s. Pool size: %s", _pool.availableObjectsCount(), _pool.getPoolSize());
39+
debug("Client conn closed. Available count : %s. Pool size: %s", this.pool.availableObjectsCount(), this.pool.getPoolSize());
4740
resolve();
4841
} catch (err) {
4942
throw new Error("error", "Error destroying redis client.");
@@ -53,76 +46,86 @@ function RedisPool (name, redisOptions, poolOptions) {
5346
};
5447

5548
// Now that the pool settings are ready create a pool instance.
56-
_pool = genericPool.createPool(factory, poolOptions);
57-
58-
// Acquire a database connection and use an optional priority.
59-
this.acquire = (priority) => {
60-
return _pool.acquire(priority);
61-
};
62-
63-
this.acquireDb = (db, priority) => {
64-
return _pool.acquire(priority)
65-
.then(client => {
66-
if (client._db_selected !== db) {
67-
client["_db_selected"] = db;
68-
client.select(db);
69-
}
70-
debug("DB selected: ", client._db_selected);
71-
});
72-
};
73-
74-
// Release a database connection to the pool.
75-
this.release = (client) => {
76-
// Always reset the DB to the default. This prevents issues
77-
// if a user used the select command to change the DB.
78-
79-
if (client._db_selected !== this._redisDb) {
80-
debug("Releasing client. Reset the DB to the given: ", this._redisDb);
81-
client.select(this._redisDb);
82-
}
83-
_pool.release(client);
84-
};
85-
86-
// Drains the connection pool and call the callback id provided.
87-
this.drain = (cb) => {
88-
_pool.drain(() => {
89-
_pool.destroyAllNow();
90-
if (cb) {
91-
cb();
49+
this.pool = genericPool.createPool(factory, poolOptions);
50+
51+
this.pool.on("factoryCreateError", e => {
52+
debug("Errored connecting Redis", e);
53+
});
54+
55+
this.pool.on("factoryDestroyError", e => {
56+
debug("Errored destroying Redis conn", e);
57+
});
58+
59+
// test connectivity by acquiring a conn
60+
// this.pool.acquire()
61+
// .then(client => this.pool.release(client));
62+
};
63+
64+
// Acquire a database connection and use an optional priority.
65+
RedisPool.prototype.acquire = function (priority) {
66+
return this.pool.acquire(priority);
67+
};
68+
69+
RedisPool.prototype.acquireDb = function (db, priority) {
70+
return this.pool.acquire(priority)
71+
.then(client => {
72+
if (client._db_selected !== db) {
73+
client["_db_selected"] = db;
74+
client.select(db);
9275
}
76+
debug("DB selected: ", client._db_selected);
9377
});
78+
};
79+
80+
// Release a database connection to the pool.
81+
RedisPool.prototype.release = function (client) {
82+
83+
// Always reset the DB to the default. This prevents issues
84+
// if a user used the select command to change the DB.
85+
if (client._db_selected !== this._redisDb) {
86+
debug("Releasing client. Reset the DB to the given: ", this._redisDb);
87+
client.select(this._redisDb);
88+
}
89+
this.pool.release(client);
90+
};
91+
92+
// Drains the connection pool and call the callback id provided.
93+
RedisPool.prototype.drain = (cb) => {
94+
this.pool.drain(() => {
95+
this.pool.destroyAllNow();
96+
if (cb) {
97+
cb();
98+
}
99+
});
100+
};
101+
102+
// Returns factory.name for this pool
103+
RedisPool.prototype.getName = function () {
104+
return this.name;
105+
};
106+
107+
RedisPool.prototype.getRedisDB = function () {
108+
return this._redisDb;
109+
};
110+
111+
RedisPool.prototype.getPoolSize = function () {
112+
return this.pool.size;
113+
};
114+
115+
RedisPool.prototype.availableObjectsCount = function () {
116+
return this.pool.available;
117+
};
118+
119+
RedisPool.prototype.waitingClientsCount = function () {
120+
return this.pool.pending;
121+
};
122+
123+
RedisPool.prototype.status = function () {
124+
return {
125+
name: this.name,
126+
size: this.pool.size,
127+
db: this._redisDb,
128+
avail: this.pool.available,
129+
waiting: this.pool.pending
94130
};
95-
96-
// Returns factory.name for this pool
97-
this.getName = () => {
98-
return this.name;
99-
};
100-
101-
this.getDB = () => {
102-
return this._redisDb;
103-
};
104-
105-
this.getPoolSize = () => {
106-
return _pool.size;
107-
};
108-
109-
this.availableObjectsCount = () => {
110-
return _pool.available;
111-
};
112-
113-
this.waitingClientsCount = () => {
114-
return _pool.pending;
115-
};
116-
117-
this.status = () => {
118-
return {
119-
name: this.name,
120-
size: _pool.size,
121-
db: this._redisDb,
122-
avail: _pool.available,
123-
waiting: _pool.pending
124-
};
125-
};
126-
}
127-
128-
module.exports = RedisPool;
131+
};

lib/redis_store.js

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,85 @@ const RedisPool = require("./redis_pool");
22

33
const debug = require("debug")("simpleRedisStore");
44

5-
function wrapFunc (pool, func) {
6-
return pool.acquire()
7-
.then((conn) => func(conn)
8-
.then((result) => {
9-
pool.release(conn);
5+
var RedisStore = module.exports = function (name, redisOptions, poolOptions) {
6+
7+
// set default pool options
8+
poolOptions = Object.assign({
9+
acquireTimeoutMillis: 50
10+
}, poolOptions || {});
11+
12+
this.name = name;
13+
this.redisOptions = redisOptions;
14+
this.poolOptions = poolOptions;
15+
this.pool = new RedisPool(name, redisOptions, poolOptions);
16+
debug("Redis store created.", this.pool.status());
17+
18+
this.getName = this.pool.getName;
19+
this.getRedisDB = this.pool.getRedisDB;
20+
this.getPoolStatus = this.pool.status;
21+
};
22+
23+
RedisStore.prototype.executeCmd = function (cmd) {
24+
return this.pool.acquire()
25+
.then(conn => cmd(conn)
26+
.then(result => {
27+
this.pool.release(conn);
1028
return result;
1129
})
1230
.catch(err => {
13-
pool.release(conn);
31+
this.pool.release(conn);
1432
throw err;
1533
}));
16-
}
17-
18-
function RedisStore (name, redisOptions, poolOptions) {
19-
20-
if (!poolOptions) {
21-
poolOptions = {};
22-
}
23-
24-
poolOptions = Object.assign({
25-
acquireTimeoutMillis: 50
26-
}, poolOptions);
27-
28-
const pool = new RedisPool(name, redisOptions, poolOptions);
29-
debug("Redis store created.", pool.status());
30-
31-
this.getName = pool.getName.bind(pool);
32-
this.getRedisDB = pool.getDB.bind(pool);
33-
this.getPoolStatus = pool.status.bind(pool);
34-
35-
this.get = (key) => wrapFunc(pool, (conn) => conn.getAsync(key));
34+
};
3635

37-
this.set = (key, value, ttlInSeconds) => {
38-
if (ttlInSeconds) {
39-
return wrapFunc(pool, (conn) => conn.setexAsync(key, ttlInSeconds, value));
40-
} else {
41-
return wrapFunc(pool, (conn) => conn.setAsync(key, value));
42-
}
43-
};
36+
RedisStore.prototype.get = function (key) {
37+
return this.executeCmd(conn => conn.getAsync(key));
38+
};
4439

45-
this.del = (key) => wrapFunc(pool, (conn) => conn.delAsync(key));
40+
RedisStore.prototype.set = function (key, value, ttlInSeconds) {
4641

47-
this.expire = (key, ttlInSeconds) => wrapFunc(pool, (conn) => conn.expireAsync(key, ttlInSeconds));
48-
49-
this.ttlInSeconds = (key) => wrapFunc(pool, (conn) => conn.ttlAsync(key));
42+
if (ttlInSeconds) {
43+
return this.executeCmd(conn => conn.setexAsync(key, ttlInSeconds, value));
44+
} else {
45+
return this.executeCmd(conn => conn.setAsync(key, value));
46+
}
47+
};
5048

51-
this.keys = (pattern) => {
52-
if (!pattern || pattern === "") {
53-
pattern = "*";
54-
}
49+
RedisStore.prototype.del = function (keys) {
50+
return this.executeCmd(conn => conn.delAsync(keys));
51+
};
5552

56-
return wrapFunc(pool, (conn) => conn.keysAsync(pattern));
57-
};
53+
RedisStore.prototype.expire = function (key, ttlInSeconds) {
54+
return this.executeCmd(conn => conn.expireAsync(key, ttlInSeconds));
55+
};
5856

59-
this.deleteAll = (pattern) => {
60-
if (!pattern || pattern === "") {
61-
pattern = "*";
62-
}
63-
debug("clearing redis keys: ", pattern);
57+
RedisStore.prototype.ttlInSeconds = function (key) {
58+
return this.executeCmd(conn => conn.ttlAsync(key));
59+
};
6460

65-
return wrapFunc(pool, (conn) => conn.keysAsync(pattern))
66-
.then(keys => {
61+
RedisStore.prototype.keys = function (pattern) {
62+
if (!pattern || pattern === "") {
63+
pattern = "*";
64+
}
6765

68-
if (keys.length > 0) {
69-
debug("deleting keys ", keys);
70-
return wrapFunc(pool, (conn) => conn.delAsync(keys));
71-
} else {
72-
debug("no keys exists with pattern: ", pattern);
73-
return Promise.resolve(true);
74-
}
75-
});
76-
};
77-
}
66+
return this.executeCmd(conn => conn.keysAsync(pattern));
67+
};
7868

79-
module.exports = RedisStore;
69+
RedisStore.prototype.deleteAll = function (pattern) {
70+
if (!pattern || pattern === "") {
71+
pattern = "*";
72+
}
73+
debug("clearing redis keys: ", pattern);
74+
75+
return this.keys(pattern)
76+
.then(keys => {
77+
78+
if (keys.length > 0) {
79+
debug("deleting keys ", keys);
80+
return this.del(keys);
81+
} else {
82+
debug("no keys exists with pattern: ", pattern);
83+
return Promise.resolve(true);
84+
}
85+
});
86+
};

0 commit comments

Comments
 (0)