Skip to content

Instantly share code, notes, and snippets.

@herrri
Created April 3, 2020 10:46
Show Gist options
  • Save herrri/8968fc5b75aae547bf59083cc4e4cfaf to your computer and use it in GitHub Desktop.
Save herrri/8968fc5b75aae547bf59083cc4e4cfaf to your computer and use it in GitHub Desktop.
Use heartbeats to select a leader node.
const PGPubsub = require("pg-pubsub");
const randInt = max => Math.floor(Math.random() * max);
const now = () => Math.floor(Date.now());
const isMyTurn = () => Math.max(...beats.map(b => b.node)) === node;
// node value
// might cause collisions,
// but let's keep it simple
const node = randInt(Number.MAX_SAFE_INTEGER);
// beats
let beats = [];
// init connection
const init = (opts = {}) => {
const config = {
instance: undefined,
db: undefined,
interval: 10000,
...opts
};
if (!config.instance && !config.db) {
throw new Error("Please check your connection");
}
const pubSub = config.instance || new PGPubsub(config.db);
// update beats
pubSub.addChannel("beats", payload => {
beats = beats.filter(b => b.time + config.interval * 2 > now());
beats.push({ ...payload, time: now() });
});
// send beat
const pubBeat = () => {
pubSub.publish("beats", { node });
};
// send beats every
setInterval(pubBeat, config.interval);
// send first beat
pubBeat();
return pubSub;
};
module.exports = {
init,
isMyTurn
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment