Comparing version 4.24.5 to 4.24.6
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("../utils"); | ||
const debug = utils_1.Debug("AbstractConnector"); | ||
class AbstractConnector { | ||
constructor() { | ||
constructor(disconnectTimeout) { | ||
this.connecting = false; | ||
this.disconnectTimeout = disconnectTimeout; | ||
} | ||
@@ -13,3 +16,9 @@ check(info) { | ||
if (this.stream) { | ||
this.stream.end(); | ||
const stream = this.stream; // Make sure callbacks refer to the same instance | ||
const timeout = setTimeout(() => { | ||
debug("stream %s:%s still open, destroying it", stream.remoteAddress, stream.remotePort); | ||
stream.destroy(); | ||
}, this.disconnectTimeout); | ||
stream.on("close", () => clearTimeout(timeout)); | ||
stream.end(); | ||
} | ||
@@ -16,0 +25,0 @@ } |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -14,3 +23,3 @@ const net_1 = require("net"); | ||
constructor(options) { | ||
super(); | ||
super(options.disconnectTimeout); | ||
this.options = options; | ||
@@ -42,3 +51,3 @@ if (!this.options.sentinels.length) { | ||
let lastError; | ||
const connectToNext = () => new Promise((resolve, reject) => { | ||
const connectToNext = () => __awaiter(this, void 0, void 0, function* () { | ||
const endpoint = this.sentinelIterator.next(); | ||
@@ -59,65 +68,65 @@ if (endpoint.done) { | ||
if (typeof retryDelay === "number") { | ||
setTimeout(() => { | ||
resolve(connectToNext()); | ||
}, retryDelay); | ||
eventEmitter("error", error); | ||
yield new Promise((resolve) => setTimeout(resolve, retryDelay)); | ||
return connectToNext(); | ||
} | ||
else { | ||
reject(error); | ||
throw error; | ||
} | ||
return; | ||
} | ||
this.resolve(endpoint.value, (err, resolved) => { | ||
if (!this.connecting) { | ||
reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)); | ||
return; | ||
let resolved = null; | ||
let err = null; | ||
try { | ||
resolved = yield this.resolve(endpoint.value); | ||
} | ||
catch (error) { | ||
err = error; | ||
} | ||
if (!this.connecting) { | ||
throw new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG); | ||
} | ||
if (resolved) { | ||
debug("resolved: %s:%s", resolved.host, resolved.port); | ||
if (this.options.enableTLSForSentinelMode && this.options.tls) { | ||
Object.assign(resolved, this.options.tls); | ||
this.stream = tls_1.connect(resolved); | ||
} | ||
if (resolved) { | ||
debug("resolved: %s:%s", resolved.host, resolved.port); | ||
if (this.options.enableTLSForSentinelMode && this.options.tls) { | ||
Object.assign(resolved, this.options.tls); | ||
this.stream = tls_1.connect(resolved); | ||
} | ||
else { | ||
this.stream = net_1.createConnection(resolved); | ||
} | ||
this.stream.once("error", (err) => { | ||
this.firstError = err; | ||
}); | ||
this.sentinelIterator.reset(true); | ||
resolve(this.stream); | ||
} | ||
else { | ||
const endpointAddress = endpoint.value.host + ":" + endpoint.value.port; | ||
const errorMsg = err | ||
? "failed to connect to sentinel " + | ||
endpointAddress + | ||
" because " + | ||
err.message | ||
: "connected to sentinel " + | ||
endpointAddress + | ||
" successfully, but got an invalid reply: " + | ||
resolved; | ||
debug(errorMsg); | ||
eventEmitter("sentinelError", new Error(errorMsg)); | ||
if (err) { | ||
lastError = err; | ||
} | ||
resolve(connectToNext()); | ||
this.stream = net_1.createConnection(resolved); | ||
} | ||
}); | ||
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 | ||
? "failed to connect to sentinel " + | ||
endpointAddress + | ||
" because " + | ||
err.message | ||
: "connected to sentinel " + | ||
endpointAddress + | ||
" successfully, but got an invalid reply: " + | ||
resolved; | ||
debug(errorMsg); | ||
eventEmitter("sentinelError", new Error(errorMsg)); | ||
if (err) { | ||
lastError = err; | ||
} | ||
return connectToNext(); | ||
} | ||
}); | ||
return connectToNext(); | ||
} | ||
updateSentinels(client, callback) { | ||
if (!this.options.updateSentinels) { | ||
return callback(null); | ||
} | ||
client.sentinel("sentinels", this.options.name, (err, result) => { | ||
if (err) { | ||
client.disconnect(); | ||
return callback(err); | ||
updateSentinels(client) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this.options.updateSentinels) { | ||
return; | ||
} | ||
const result = yield client.sentinel("sentinels", this.options.name); | ||
if (!Array.isArray(result)) { | ||
return callback(null); | ||
return; | ||
} | ||
@@ -138,30 +147,18 @@ result | ||
debug("Updated internal sentinels: %s", this.sentinelIterator); | ||
callback(null); | ||
}); | ||
} | ||
resolveMaster(client, callback) { | ||
client.sentinel("get-master-addr-by-name", this.options.name, (err, result) => { | ||
if (err) { | ||
client.disconnect(); | ||
return callback(err); | ||
} | ||
this.updateSentinels(client, (err) => { | ||
client.disconnect(); | ||
if (err) { | ||
return callback(err); | ||
} | ||
callback(null, this.sentinelNatResolve(Array.isArray(result) | ||
? { host: result[0], port: Number(result[1]) } | ||
: null)); | ||
}); | ||
resolveMaster(client) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const result = yield client.sentinel("get-master-addr-by-name", this.options.name); | ||
yield this.updateSentinels(client); | ||
return this.sentinelNatResolve(Array.isArray(result) | ||
? { host: result[0], port: Number(result[1]) } | ||
: null); | ||
}); | ||
} | ||
resolveSlave(client, callback) { | ||
client.sentinel("slaves", this.options.name, (err, result) => { | ||
client.disconnect(); | ||
if (err) { | ||
return callback(err); | ||
} | ||
resolveSlave(client) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const result = yield client.sentinel("slaves", this.options.name); | ||
if (!Array.isArray(result)) { | ||
return callback(null, null); | ||
return null; | ||
} | ||
@@ -171,3 +168,3 @@ const availableSlaves = result | ||
.filter((slave) => slave.flags && !slave.flags.match(/(disconnected|s_down|o_down)/)); | ||
callback(null, this.sentinelNatResolve(selectPreferredSentinel(availableSlaves, this.options.preferredSlaves))); | ||
return this.sentinelNatResolve(selectPreferredSentinel(availableSlaves, this.options.preferredSlaves)); | ||
}); | ||
@@ -180,26 +177,33 @@ } | ||
} | ||
resolve(endpoint, callback) { | ||
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, | ||
dropBufferSupport: true, | ||
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, | ||
dropBufferSupport: true, | ||
}); | ||
// ignore the errors since resolve* methods will handle them | ||
client.on("error", noop); | ||
try { | ||
if (this.options.role === "slave") { | ||
return yield this.resolveSlave(client); | ||
} | ||
else { | ||
return yield this.resolveMaster(client); | ||
} | ||
} | ||
finally { | ||
client.disconnect(); | ||
} | ||
}); | ||
// ignore the errors since resolve* methods will handle them | ||
client.on("error", noop); | ||
if (this.options.role === "slave") { | ||
this.resolveSlave(client, callback); | ||
} | ||
else { | ||
this.resolveMaster(client, callback); | ||
} | ||
} | ||
@@ -206,0 +210,0 @@ } |
@@ -13,3 +13,3 @@ "use strict"; | ||
constructor(options) { | ||
super(); | ||
super(options.disconnectTimeout); | ||
this.options = options; | ||
@@ -16,0 +16,0 @@ } |
@@ -9,2 +9,3 @@ "use strict"; | ||
connectTimeout: 10000, | ||
disconnectTimeout: 2000, | ||
retryStrategy: function (times) { | ||
@@ -11,0 +12,0 @@ return Math.min(times * 50, 2000); |
@@ -0,1 +1,8 @@ | ||
## [4.24.6](https://github.com/luin/ioredis/compare/v4.24.5...v4.24.6) (2021-03-31) | ||
### Bug Fixes | ||
* force disconnect after a timeout if socket is still half-open ([#1318](https://github.com/luin/ioredis/issues/1318)) ([6cacd17](https://github.com/luin/ioredis/commit/6cacd17e6ac4d9f995728ee09777e0a7f3b739d7)) | ||
## [4.24.5](https://github.com/luin/ioredis/compare/v4.24.4...v4.24.5) (2021-03-27) | ||
@@ -2,0 +9,0 @@ |
{ | ||
"name": "ioredis", | ||
"version": "4.24.5", | ||
"version": "4.24.6", | ||
"description": "A robust, performance-focused and full-featured Redis client for Node.js.", | ||
@@ -61,3 +61,3 @@ "main": "built/index.js", | ||
"@types/uuid": "^8.3.0", | ||
"@typescript-eslint/eslint-plugin": "^2.26.0", | ||
"@typescript-eslint/eslint-plugin": "^1.13.0", | ||
"@typescript-eslint/parser": "^2.26.0", | ||
@@ -69,6 +69,6 @@ "bluebird": "^3.7.2", | ||
"cz-conventional-changelog": "^3.1.0", | ||
"eslint": "^6.8.0", | ||
"eslint": "^5.16.0", | ||
"eslint-config-prettier": "^6.10.1", | ||
"husky": "^4.2.3", | ||
"mocha": "^7.1.1", | ||
"mocha": "^6.2.3", | ||
"prettier": "^2.0.2", | ||
@@ -75,0 +75,0 @@ "pretty-quick": "^2.0.1", |
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
278785
4653