Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Redis concurrency control
const redis = require('redis');
const bluebird = require('bluebird');
const redisClient = redis.createClient({});
bluebird.promisifyAll(Object.getPrototypeOf(redisClient));
const luaScript = `
local newPayload = ARGV[1]
local newVersionStr, newData = ARGV[1]:match("^([0-9]+)|(.+)$")
local prevVal = redis.call("get", KEYS[1]) or nil
if prevVal == nil then
return redis.call("set", KEYS[1], "1|" .. newData)
end
local oldVersionStr, oldData = prevVal:match("^([0-9]+)|(.+)$")
local newVersion = tonumber(newVersionStr)
local oldVersion = tonumber(oldVersionStr)
-- check if version matches before writing
if oldVersion == (newVersion - 1) then
return redis.call('set', KEYS[1], newPayload)
else
return nil
end
`;
(async () => {
const results = await Promise.all([
redisClient.evalAsync(luaScript, 1, 'cc', '1|{a: 1}'),
redisClient.evalAsync(luaScript, 1, 'cc', '1|{b: 2}'),
redisClient.evalAsync(luaScript, 1, 'cc', '2|{b: 2}'),
]);
console.log(results); // potential output [ 'OK', null, 'OK' ]
console.log(await redisClient.getAsync('cc'));
console.log(await redisClient.delAsync('cc'));
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.