fix(#9508): switch to ioredis (#9545)

* switch to ioredis

also need this fix in redisearch:

redis-search.js:98
```
  redisClient.multi(cmds).exec(function(err, ids) {
    if (err) {
      return callback(err);
    }
    var errRes = ids[resultIndex];
    if (errRes[0]) {
      return callback(errRes[0]);
    }
    callback(null, errRes[1]);
  });
```

* dbsearch compatible with ioredis

* fixed dbsearch?
v1.18.x
Peter Jaszkowiak 4 years ago committed by GitHub
parent 53335677e3
commit dd81dd03e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -85,7 +85,7 @@
"@nodebb/bootswatch": "3.4.2", "@nodebb/bootswatch": "3.4.2",
"nconf": "^0.11.2", "nconf": "^0.11.2",
"nodebb-plugin-composer-default": "6.5.27", "nodebb-plugin-composer-default": "6.5.27",
"nodebb-plugin-dbsearch": "4.2.0", "nodebb-plugin-dbsearch": "5.0.1",
"nodebb-plugin-emoji": "^3.5.0", "nodebb-plugin-emoji": "^3.5.0",
"nodebb-plugin-emoji-android": "2.0.5", "nodebb-plugin-emoji-android": "2.0.5",
"nodebb-plugin-markdown": "8.12.10", "nodebb-plugin-markdown": "8.12.10",
@ -107,7 +107,7 @@
"postcss": "8.2.15", "postcss": "8.2.15",
"postcss-clean": "1.2.0", "postcss-clean": "1.2.0",
"prompt": "^1.1.0", "prompt": "^1.1.0",
"redis": "3.1.2", "ioredis": "4.27.2",
"request": "2.88.2", "request": "2.88.2",
"request-promise-native": "^1.0.9", "request-promise-native": "^1.0.9",
"requirejs": "2.3.6", "requirejs": "2.3.6",

@ -1,37 +1,34 @@
'use strict'; 'use strict';
const nconf = require('nconf'); const nconf = require('nconf');
const redis = require('redis'); const Redis = require('ioredis');
const winston = require('winston'); const winston = require('winston');
const _ = require('lodash');
const connection = module.exports; const connection = module.exports;
connection.getConnectionOptions = function (redis) {
redis = redis || nconf.get('redis');
const connOptions = {};
if (redis.password) {
connOptions.auth_pass = redis.password;
}
if (redis.hasOwnProperty('database')) {
connOptions.db = redis.database;
}
return _.merge(connOptions, redis.options || {});
};
connection.connect = async function (options) { connection.connect = async function (options) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
options = options || nconf.get('redis'); options = options || nconf.get('redis');
const redis_socket_or_host = options.host; const redis_socket_or_host = options.host;
const connOptions = connection.getConnectionOptions(options);
let cxn; let cxn;
if (redis_socket_or_host && String(redis_socket_or_host).indexOf('/') >= 0) { if (redis_socket_or_host && String(redis_socket_or_host).indexOf('/') >= 0) {
/* If redis.host contains a path name character, use the unix dom sock connection. ie, /tmp/redis.sock */ // If redis.host contains a path name character, use the unix dom sock connection. ie, /tmp/redis.sock
cxn = redis.createClient(options.host, connOptions); cxn = new Redis({
...options.options,
path: redis_socket_or_host,
password: options.password,
db: options.database,
});
} else { } else {
/* Else, connect over tcp/ip */ // Else, connect over tcp/ip
cxn = redis.createClient(options.port, options.host, connOptions); cxn = new Redis({
...options.options,
host: redis_socket_or_host,
port: options.port,
password: options.password,
db: options.database,
});
} }
const dbIdx = parseInt(options.database, 10); const dbIdx = parseInt(options.database, 10);
@ -44,6 +41,8 @@ connection.connect = async function (options) {
reject(err); reject(err);
}); });
cxn.on('ready', () => { cxn.on('ready', () => {
// back-compat with node_redis
cxn.batch = cxn.pipeline;
resolve(cxn); resolve(cxn);
}); });

@ -111,6 +111,14 @@ module.exports = function (module) {
data = [await module.client.async.hgetall(unCachedKeys[0])]; data = [await module.client.async.hgetall(unCachedKeys[0])];
} }
// convert empty objects into null for back-compat with node_redis
data = data.map((elem) => {
if (!Object.keys(elem).length) {
return null;
}
return elem;
});
unCachedKeys.forEach((key, i) => { unCachedKeys.forEach((key, i) => {
cachedData[key] = data[i] || null; cachedData[key] = data[i] || null;
cache.set(key, cachedData[key]); cache.set(key, cachedData[key]);

@ -1,14 +1,17 @@
'use strict'; 'use strict';
const util = require('util');
const helpers = module.exports; const helpers = module.exports;
helpers.noop = function () {}; helpers.noop = function () {};
helpers.execBatch = async function (batch) { helpers.execBatch = async function (batch) {
const proFn = util.promisify(batch.exec).bind(batch); const results = await batch.exec();
return await proFn(); return results.map(([err, res]) => {
if (err) {
throw err;
}
return res;
});
}; };
helpers.resultsToBool = function (results) { helpers.resultsToBool = function (results) {

@ -29,6 +29,9 @@ module.exports = function (module) {
if (!Array.isArray(key)) { if (!Array.isArray(key)) {
key = [key]; key = [key];
} }
if (!value.length) {
return;
}
const batch = module.client.batch(); const batch = module.client.batch();
key.forEach(k => batch.srem(String(k), value)); key.forEach(k => batch.srem(String(k), value));

Loading…
Cancel
Save