Comparing version 1.0.0 to 1.1.0
# Changelog | ||
## [1.1.0](https://github.com/alexzel/iomem/compare/v1.0.0...v1.1.0) (2023-01-25) | ||
### Features | ||
* implement failover servers ([e51acb3](https://github.com/alexzel/iomem/commit/e51acb3459289950470f3f317feb0b150c8badf4)) | ||
## [1.0.0](https://github.com/alexzel/iomem/compare/v0.2.4...v1.0.0) (2023-01-25) | ||
@@ -4,0 +11,0 @@ |
{ | ||
"name": "iomem", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Memcached client with binary protocol support and multi keys commands", | ||
@@ -8,2 +8,3 @@ "keywords": [ | ||
"memcache", | ||
"memcached", | ||
"memcached-client", | ||
@@ -14,3 +15,2 @@ "binary-protocol", | ||
"elasticache", | ||
"cluster", | ||
"multi", | ||
@@ -57,3 +57,6 @@ "multi-get", | ||
"hashring": "^3.2.0" | ||
}, | ||
"engines": { | ||
"node": ">=16.0.0" | ||
} | ||
} |
@@ -12,3 +12,5 @@ # `iomem` | ||
- Server failover | ||
- Optional values compression | ||
- Optional keys hashing | ||
- Optional KeepAlive for sockets | ||
- Add types for TypeScript | ||
@@ -92,3 +94,5 @@ | ||
retriesDelay: 100, // request retries - initial delay | ||
retriesFactor: 2 // request retries - exponential factor | ||
retriesFactor: 2, // request retries - exponential factor | ||
maxFailures: 10, // max server failures to swap server with a failover server | ||
failoverServers: [] // failover servers list | ||
} | ||
@@ -95,0 +99,0 @@ ``` |
@@ -15,3 +15,5 @@ 'use strict' | ||
retriesDelay: 100, // request retries - initial delay | ||
retriesFactor: 2 // request retries - exponential factor | ||
retriesFactor: 2, // request retries - exponential factor | ||
maxFailures: 10, // max server failures to swap server with a failover server | ||
failoverServers: [] // failover servers list | ||
} | ||
@@ -18,0 +20,0 @@ |
@@ -40,3 +40,10 @@ 'use strict' | ||
constructor (options = {}) { | ||
const { getKeysSetByServer, getKeysMapByServer, getKeysSetByAllServers, config = {}, ...opts } = options | ||
const { | ||
getKeysSetByServer, | ||
getKeysMapByServer, | ||
getKeysSetByAllServers, | ||
serverFailure, | ||
config = {}, | ||
...opts | ||
} = options | ||
super({ objectMode: true, ...opts }) | ||
@@ -46,2 +53,3 @@ this.getKeysSetByServer = getKeysSetByServer | ||
this.getKeysSetByAllServers = getKeysSetByAllServers | ||
this.serverFailure = serverFailure | ||
this.config = config | ||
@@ -95,2 +103,3 @@ } | ||
cleanup.clean() | ||
this.serverFailure(server) | ||
cb(new Error(`iomem: request timeout (${this.config.timeout})`)) | ||
@@ -203,2 +212,5 @@ }, this.config.timeout) // maybe use connectionTimeout when sock.readyState === 'opening' || sock.readyState === 'closed'? | ||
this._failovers = this._options.failoverServers.map(address => | ||
new Server(address, this._options.maxConnections, this._options.connectionTimeout)) | ||
this._ring = new HashRing([...this._servers.keys()], HASHRING_ALGORITHM, { | ||
@@ -241,3 +253,3 @@ compatibility: HASHRING_COMPATIBILITY, | ||
getKeysSetByAllServers = (key) => { | ||
getKeysSetByAllServers = key => { | ||
const map = new Map() | ||
@@ -248,2 +260,31 @@ this._servers.forEach(server => map.set(server, new Set([key]))) | ||
serverFailure = server => { | ||
// all the below makes sense only when we have some failover servers | ||
if (this._failovers.length) { | ||
// server is already failed, so nothing | ||
if (server.isFailed()) { | ||
return | ||
} | ||
// server has failed, but we still hope it's alive | ||
if (server.fail() < this._options.maxFailures) { | ||
return | ||
} | ||
// take a server from failovers and push failed server to the end | ||
const failover = this._failovers.shift() | ||
this._failovers.push(server) | ||
// don't forget to revive the server in case it failed previously failed | ||
failover.revive() | ||
// add failover server into servers map | ||
this._servers.set(failover.hostname, failover) | ||
this._ring.swap(server.hostname, failover.hostname) | ||
// end failed server | ||
server.end() | ||
} | ||
} | ||
query (args = []) { | ||
@@ -254,2 +295,3 @@ const net = new NetStream({ | ||
getKeysSetByAllServers: this.getKeysSetByAllServers, | ||
serverFailure: this.serverFailure, | ||
config: this._options | ||
@@ -256,0 +298,0 @@ }) |
@@ -39,2 +39,4 @@ 'use strict' | ||
this._timeout = timeout | ||
this.revive() | ||
} | ||
@@ -88,2 +90,15 @@ | ||
isFailed () { | ||
return this._failed | ||
} | ||
fail () { | ||
return ++this._failures | ||
} | ||
revive () { | ||
this._failures = 0 | ||
this._failed = false | ||
} | ||
end () { | ||
@@ -90,0 +105,0 @@ this._sockets.forEach(sock => sock.end()) |
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
54760
1155
400