forked from ttc/micro-service-api
-first commit
This commit is contained in:
154
node_modules/ioredis/built/cluster/ConnectionPool.js
generated
vendored
Normal file
154
node_modules/ioredis/built/cluster/ConnectionPool.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const events_1 = require("events");
|
||||
const utils_1 = require("../utils");
|
||||
const util_1 = require("./util");
|
||||
const Redis_1 = require("../Redis");
|
||||
const debug = (0, utils_1.Debug)("cluster:connectionPool");
|
||||
class ConnectionPool extends events_1.EventEmitter {
|
||||
constructor(redisOptions) {
|
||||
super();
|
||||
this.redisOptions = redisOptions;
|
||||
// master + slave = all
|
||||
this.nodes = {
|
||||
all: {},
|
||||
master: {},
|
||||
slave: {},
|
||||
};
|
||||
this.specifiedOptions = {};
|
||||
}
|
||||
getNodes(role = "all") {
|
||||
const nodes = this.nodes[role];
|
||||
return Object.keys(nodes).map((key) => nodes[key]);
|
||||
}
|
||||
getInstanceByKey(key) {
|
||||
return this.nodes.all[key];
|
||||
}
|
||||
getSampleInstance(role) {
|
||||
const keys = Object.keys(this.nodes[role]);
|
||||
const sampleKey = (0, utils_1.sample)(keys);
|
||||
return this.nodes[role][sampleKey];
|
||||
}
|
||||
/**
|
||||
* Add a master node to the pool
|
||||
* @param node
|
||||
*/
|
||||
addMasterNode(node) {
|
||||
const key = (0, util_1.getNodeKey)(node.options);
|
||||
const redis = this.createRedisFromOptions(node, node.options.readOnly);
|
||||
//Master nodes aren't read-only
|
||||
if (!node.options.readOnly) {
|
||||
this.nodes.all[key] = redis;
|
||||
this.nodes.master[key] = redis;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Creates a Redis connection instance from the node options
|
||||
* @param node
|
||||
* @param readOnly
|
||||
*/
|
||||
createRedisFromOptions(node, readOnly) {
|
||||
const redis = new Redis_1.default((0, utils_1.defaults)({
|
||||
// Never try to reconnect when a node is lose,
|
||||
// instead, waiting for a `MOVED` error and
|
||||
// fetch the slots again.
|
||||
retryStrategy: null,
|
||||
// Offline queue should be enabled so that
|
||||
// we don't need to wait for the `ready` event
|
||||
// before sending commands to the node.
|
||||
enableOfflineQueue: true,
|
||||
readOnly: readOnly,
|
||||
}, node, this.redisOptions, { lazyConnect: true }));
|
||||
return redis;
|
||||
}
|
||||
/**
|
||||
* Find or create a connection to the node
|
||||
*/
|
||||
findOrCreate(node, readOnly = false) {
|
||||
const key = (0, util_1.getNodeKey)(node);
|
||||
readOnly = Boolean(readOnly);
|
||||
if (this.specifiedOptions[key]) {
|
||||
Object.assign(node, this.specifiedOptions[key]);
|
||||
}
|
||||
else {
|
||||
this.specifiedOptions[key] = node;
|
||||
}
|
||||
let redis;
|
||||
if (this.nodes.all[key]) {
|
||||
redis = this.nodes.all[key];
|
||||
if (redis.options.readOnly !== readOnly) {
|
||||
redis.options.readOnly = readOnly;
|
||||
debug("Change role of %s to %s", key, readOnly ? "slave" : "master");
|
||||
redis[readOnly ? "readonly" : "readwrite"]().catch(utils_1.noop);
|
||||
if (readOnly) {
|
||||
delete this.nodes.master[key];
|
||||
this.nodes.slave[key] = redis;
|
||||
}
|
||||
else {
|
||||
delete this.nodes.slave[key];
|
||||
this.nodes.master[key] = redis;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
debug("Connecting to %s as %s", key, readOnly ? "slave" : "master");
|
||||
redis = this.createRedisFromOptions(node, readOnly);
|
||||
this.nodes.all[key] = redis;
|
||||
this.nodes[readOnly ? "slave" : "master"][key] = redis;
|
||||
redis.once("end", () => {
|
||||
this.removeNode(key);
|
||||
this.emit("-node", redis, key);
|
||||
if (!Object.keys(this.nodes.all).length) {
|
||||
this.emit("drain");
|
||||
}
|
||||
});
|
||||
this.emit("+node", redis, key);
|
||||
redis.on("error", function (error) {
|
||||
this.emit("nodeError", error, key);
|
||||
});
|
||||
}
|
||||
return redis;
|
||||
}
|
||||
/**
|
||||
* Reset the pool with a set of nodes.
|
||||
* The old node will be removed.
|
||||
*/
|
||||
reset(nodes) {
|
||||
debug("Reset with %O", nodes);
|
||||
const newNodes = {};
|
||||
nodes.forEach((node) => {
|
||||
const key = (0, util_1.getNodeKey)(node);
|
||||
// Don't override the existing (master) node
|
||||
// when the current one is slave.
|
||||
if (!(node.readOnly && newNodes[key])) {
|
||||
newNodes[key] = node;
|
||||
}
|
||||
});
|
||||
Object.keys(this.nodes.all).forEach((key) => {
|
||||
if (!newNodes[key]) {
|
||||
debug("Disconnect %s because the node does not hold any slot", key);
|
||||
this.nodes.all[key].disconnect();
|
||||
this.removeNode(key);
|
||||
}
|
||||
});
|
||||
Object.keys(newNodes).forEach((key) => {
|
||||
const node = newNodes[key];
|
||||
this.findOrCreate(node, node.readOnly);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Remove a node from the pool.
|
||||
*/
|
||||
removeNode(key) {
|
||||
const { nodes } = this;
|
||||
if (nodes.all[key]) {
|
||||
debug("Remove %s from the pool", key);
|
||||
delete nodes.all[key];
|
||||
}
|
||||
delete nodes.master[key];
|
||||
delete nodes.slave[key];
|
||||
}
|
||||
}
|
||||
exports.default = ConnectionPool;
|
||||
Reference in New Issue
Block a user