The Safe Redis Leader JS module is designed to provide a leader election implementation that provides tested gaurentees that there is only a single leader elected from a group of clients at one time.
The implementation is a port of the stale Redis Leader npm package that implements a solution to the known race condition. Additionally, this rewritten package:
- Removes the usage of
.bind
andthis
, as well as prototype inheritance (Without introducing classes in the main impl) - Only exposes public api functions that should be exposed (no more public-but-should-be-private
_elect
fn) - has a test suite within docker-compose using a real redis instance, which allows anyone to run the tests with no heavy dependency setup
- Has tests to assert the known race condition can no longer occur
- removes the need for
new
, by providing a simplecreateSafeRedisLeader(...)
public fn - Replace callback-hell with async/await
Install the package:
npm install --save safe-redis-leader
in one terminal, run the follow index.js:
const {createSafeRedisLeader} = require('safe-redis-leader')
const Redis = require('ioredis')
async function main(){
const asyncRedis = new Redis({
host: "locahost",
port: 6379,
password: "some-password"
})
const leaderElectionKey = 'the-election'
const safeLeader = await createSafeRedisLeader({
asyncRedis: asyncRedis,
ttl: 1500,
wait: 3000,
key: leaderElectionKey
})
safeLeader.on("elected", ()=>{
console.log("I'm the leader - 1")
})
await safeLeader.elect()
}
main().catch((e)=>{
console.error(e)
process.exit(1)
})
In a seperate terminal/tab, run the following index.js:
const {createSafeRedisLeader} = require('safe-redis-leader')
const Redis = require('ioredis')
async function main(){
const asyncRedis = new Redis({
host: "locahost",
port: 6379,
password: "some-password"
})
const leaderElectionKey = 'the-election'
const safeLeader = await createSafeRedisLeader({
asyncRedis: asyncRedis,
ttl: 1500,
wait: 3000,
key: leaderElectionKey
})
safeLeader.on("elected", ()=>{
console.log("I'm the leader - 2")
})
await safeLeader.elect()
}
main().catch((e)=>{
console.error(e)
process.exit(1)
})
npm run docker:test
MIT