Comparing version 4.26.0 to 4.27.0
@@ -20,2 +20,3 @@ "use strict"; | ||
const redis_1 = require("../../redis"); | ||
const FailoverDetector_1 = require("./FailoverDetector"); | ||
const debug = utils_1.Debug("SentinelConnector"); | ||
@@ -26,2 +27,4 @@ class SentinelConnector extends AbstractConnector_1.default { | ||
this.options = options; | ||
this.failoverDetector = null; | ||
this.emitter = null; | ||
if (!this.options.sentinels.length) { | ||
@@ -48,2 +51,8 @@ throw new Error("Requires at least one sentinel to connect to."); | ||
} | ||
disconnect() { | ||
super.disconnect(); | ||
if (this.failoverDetector) { | ||
this.failoverDetector.cleanup(); | ||
} | ||
} | ||
connect(eventEmitter) { | ||
@@ -88,4 +97,5 @@ this.connecting = true; | ||
} | ||
const endpointAddress = endpoint.value.host + ":" + endpoint.value.port; | ||
if (resolved) { | ||
debug("resolved: %s:%s", resolved.host, resolved.port); | ||
debug("resolved: %s:%s from sentinel %s", resolved.host, resolved.port, endpointAddress); | ||
if (this.options.enableTLSForSentinelMode && this.options.tls) { | ||
@@ -98,10 +108,9 @@ Object.assign(resolved, this.options.tls); | ||
} | ||
this.stream.once("connect", () => this.initFailoverDetector()); | ||
this.stream.once("error", (err) => { | ||
this.firstError = err; | ||
}); | ||
this.sentinelIterator.reset(true); | ||
return this.stream; | ||
} | ||
else { | ||
const endpointAddress = endpoint.value.host + ":" + endpoint.value.port; | ||
const errorMsg = err | ||
@@ -177,20 +186,11 @@ ? "failed to connect to sentinel " + | ||
} | ||
connectToSentinel(endpoint, options) { | ||
return new redis_1.default(Object.assign({ port: endpoint.port || 26379, host: endpoint.host, username: this.options.sentinelUsername || null, password: this.options.sentinelPassword || null, family: endpoint.family || | ||
(StandaloneConnector_1.isIIpcConnectionOptions(this.options) | ||
? undefined | ||
: this.options.family), tls: this.options.sentinelTLS, retryStrategy: null, enableReadyCheck: false, connectTimeout: this.options.connectTimeout, commandTimeout: this.options.sentinelCommandTimeout, dropBufferSupport: true }, options)); | ||
} | ||
resolve(endpoint) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const client = new redis_1.default({ | ||
port: endpoint.port || 26379, | ||
host: endpoint.host, | ||
username: this.options.sentinelUsername || null, | ||
password: this.options.sentinelPassword || null, | ||
family: endpoint.family || | ||
(StandaloneConnector_1.isIIpcConnectionOptions(this.options) | ||
? undefined | ||
: this.options.family), | ||
tls: this.options.sentinelTLS, | ||
retryStrategy: null, | ||
enableReadyCheck: false, | ||
connectTimeout: this.options.connectTimeout, | ||
commandTimeout: this.options.sentinelCommandTimeout, | ||
dropBufferSupport: true, | ||
}); | ||
const client = this.connectToSentinel(endpoint); | ||
// ignore the errors since resolve* methods will handle them | ||
@@ -211,2 +211,36 @@ client.on("error", noop); | ||
} | ||
initFailoverDetector() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// Move the current sentinel to the first position | ||
this.sentinelIterator.reset(true); | ||
const sentinels = []; | ||
// In case of a large amount of sentinels, limit the number of concurrent connections | ||
while (sentinels.length < this.options.sentinelMaxConnections) { | ||
const { done, value } = this.sentinelIterator.next(); | ||
if (done) { | ||
break; | ||
} | ||
const client = this.connectToSentinel(value, { | ||
lazyConnect: true, | ||
retryStrategy: this.options.sentinelReconnectStrategy, | ||
}); | ||
client.on("reconnecting", () => { | ||
var _a; | ||
// Tests listen to this event | ||
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit("sentinelReconnecting"); | ||
}); | ||
sentinels.push({ address: value, client }); | ||
} | ||
this.sentinelIterator.reset(false); | ||
if (this.failoverDetector) { | ||
// Clean up previous detector | ||
this.failoverDetector.cleanup(); | ||
} | ||
this.failoverDetector = new FailoverDetector_1.FailoverDetector(this, sentinels); | ||
yield this.failoverDetector.subscribe(); | ||
// Tests listen to this event | ||
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit("failoverSubscribed"); | ||
}); | ||
} | ||
} | ||
@@ -213,0 +247,0 @@ exports.default = SentinelConnector; |
@@ -135,3 +135,5 @@ "use strict"; | ||
else if (this.options.sentinels) { | ||
this.connector = new connectors_1.SentinelConnector(this.options); | ||
const sentinelConnector = new connectors_1.SentinelConnector(this.options); | ||
sentinelConnector.emitter = this; | ||
this.connector = sentinelConnector; | ||
} | ||
@@ -138,0 +140,0 @@ else { |
@@ -23,2 +23,10 @@ "use strict"; | ||
}, | ||
sentinelReconnectStrategy: function () { | ||
// This strategy only applies when sentinels are used for detecting | ||
// a failover, not during initial master resolution. | ||
// The deployment can still function when some of the sentinels are down | ||
// for a long period of time, so we may not want to attempt reconnection | ||
// very often. Therefore the default interval is fairly long (1 minute). | ||
return 60000; | ||
}, | ||
natMap: null, | ||
@@ -47,2 +55,3 @@ enableTLSForSentinelMode: false, | ||
maxScriptsCachingTime: 60000, | ||
sentinelMaxConnections: 10, | ||
}; |
@@ -0,1 +1,8 @@ | ||
# [4.27.0](https://github.com/luin/ioredis/compare/v4.26.0...v4.27.0) (2021-04-24) | ||
### Features | ||
* **sentinel:** detect failover from +switch-master messages ([#1328](https://github.com/luin/ioredis/issues/1328)) ([a464151](https://github.com/luin/ioredis/commit/a46415187d32bfdc974072403edb8aca2df282d6)) | ||
# [4.26.0](https://github.com/luin/ioredis/compare/v4.25.0...v4.26.0) (2021-04-08) | ||
@@ -2,0 +9,0 @@ |
{ | ||
"name": "ioredis", | ||
"version": "4.26.0", | ||
"version": "4.27.0", | ||
"description": "A robust, performance-focused and full-featured Redis client for Node.js.", | ||
@@ -5,0 +5,0 @@ "main": "built/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
287131
38
4773