171 lines
4.6 KiB
JavaScript
171 lines
4.6 KiB
JavaScript
var redis = require('redis');
|
|
var winston = require('winston');
|
|
|
|
// For storing in redis or KeyDB (Redis API compatible)
|
|
// options[type] = redis
|
|
// options[host] - The host to connect to (default localhost)
|
|
// options[port] - The port to connect to (default 6379)
|
|
// options[db] - The db to use (default 0)
|
|
// options[password] - The password to use (if any)
|
|
// options[expire] - The time to live for each key set (default never)
|
|
// options[connectionTimeout] - Connection timeout in ms (default 5000)
|
|
|
|
var RedisDocumentStore = function(options, client) {
|
|
this.expire = options.expire;
|
|
if (client) {
|
|
winston.info('using predefined redis client');
|
|
RedisDocumentStore.client = client;
|
|
|
|
// Check if we need to promisify the client (for redis-url 0.1.0)
|
|
if (!RedisDocumentStore.client.connect && !RedisDocumentStore.isLegacyClient) {
|
|
winston.info('using legacy redis client from redis-url');
|
|
RedisDocumentStore.isLegacyClient = true;
|
|
}
|
|
} else if (!RedisDocumentStore.client) {
|
|
winston.info('configuring redis/keydb client');
|
|
RedisDocumentStore.connect(options);
|
|
}
|
|
};
|
|
|
|
// Create a connection according to config
|
|
RedisDocumentStore.connect = async function(options) {
|
|
var host = options.host || '127.0.0.1';
|
|
var port = options.port || 6379;
|
|
var index = options.db || 0;
|
|
var connectionTimeout = options.connectionTimeout || 5000;
|
|
|
|
const redisOptions = {
|
|
socket: {
|
|
host: host,
|
|
port: port,
|
|
connectTimeout: connectionTimeout
|
|
},
|
|
database: index
|
|
};
|
|
|
|
// Add password if provided
|
|
if (options.password) {
|
|
redisOptions.password = options.password;
|
|
}
|
|
|
|
// Add URL if provided (overrides other options)
|
|
if (options.url) {
|
|
delete redisOptions.socket;
|
|
delete redisOptions.database;
|
|
redisOptions.url = options.url;
|
|
}
|
|
|
|
try {
|
|
RedisDocumentStore.client = redis.createClient(redisOptions);
|
|
|
|
// Set up error handling
|
|
RedisDocumentStore.client.on('error', (err) => {
|
|
winston.error('Redis/KeyDB error', { error: err });
|
|
});
|
|
|
|
// Connect the client
|
|
await RedisDocumentStore.client.connect();
|
|
|
|
winston.info('connected to redis/keydb on ' + host + ':' + port + '/' + index);
|
|
}
|
|
catch (err) {
|
|
winston.error('error connecting to redis/keydb', { error: err });
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
// Save file in a key
|
|
RedisDocumentStore.prototype.set = async function(key, data, callback, skipExpire) {
|
|
var _this = this;
|
|
|
|
try {
|
|
// Handle legacy client (redis-url 0.1.0)
|
|
if (RedisDocumentStore.isLegacyClient) {
|
|
RedisDocumentStore.client.set(key, data, function(err) {
|
|
if (err) {
|
|
winston.error('error setting key', { error: err });
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (!skipExpire) {
|
|
_this.setExpiration(key);
|
|
}
|
|
callback(true);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Modern redis 4.x client
|
|
await RedisDocumentStore.client.set(key, data);
|
|
|
|
if (!skipExpire) {
|
|
_this.setExpiration(key);
|
|
}
|
|
callback(true);
|
|
}
|
|
catch (err) {
|
|
winston.error('error setting key', { error: err });
|
|
callback(false);
|
|
}
|
|
};
|
|
|
|
// Expire a key in expire time if set
|
|
RedisDocumentStore.prototype.setExpiration = async function(key) {
|
|
if (this.expire) {
|
|
try {
|
|
if (RedisDocumentStore.isLegacyClient) {
|
|
RedisDocumentStore.client.expire(key, this.expire, function(err) {
|
|
if (err) {
|
|
winston.error('failed to set expiry on key: ' + key, { error: err });
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
await RedisDocumentStore.client.expire(key, this.expire);
|
|
}
|
|
catch (err) {
|
|
winston.error('failed to set expiry on key: ' + key, { error: err });
|
|
}
|
|
}
|
|
};
|
|
|
|
// Get a file from a key
|
|
RedisDocumentStore.prototype.get = async function(key, callback, skipExpire) {
|
|
var _this = this;
|
|
|
|
try {
|
|
// Handle legacy client (redis-url 0.1.0)
|
|
if (RedisDocumentStore.isLegacyClient) {
|
|
RedisDocumentStore.client.get(key, function(err, reply) {
|
|
if (err) {
|
|
winston.error('error getting key', { error: err });
|
|
callback(false);
|
|
return;
|
|
}
|
|
|
|
if (reply && !skipExpire) {
|
|
_this.setExpiration(key);
|
|
}
|
|
callback(reply);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Modern redis 4.x client
|
|
const reply = await RedisDocumentStore.client.get(key);
|
|
|
|
if (reply && !skipExpire) {
|
|
_this.setExpiration(key);
|
|
}
|
|
callback(reply);
|
|
}
|
|
catch (err) {
|
|
winston.error('error getting key', { error: err });
|
|
callback(false);
|
|
}
|
|
};
|
|
|
|
module.exports = RedisDocumentStore;
|