Reputation: 4014
Redis recommends a method of using SET
with optional parameters as a locking mechanism. I.e. SET lock 1 EX 10 NX
will set a lock only if it does not already exists and it will expire after 10 second.
I'm using Node Redis, which has a set()
method, but I'm not sure how to pass it the additional parameters to have the key expire and not be created if it already exists, or even if it's possible.
Perhaps I have to use setnx()
and expire()
as separate calls?
Upvotes: 22
Views: 32969
Reputation: 1203
It's worth noting that node-redis
v4
onwards, the package has undergone significant changes, one of which is that the functions return promises by default and modifiers to commands can be specified using a JavaScript object as a optional parameter:
await client.set('key', 'value', {
EX: 300,
NX: true
});
Also, you can run whatever command you want using sendCommand
:
await client.sendCommand(['SET', 'key', 'value', 'NX', 'EX', 300]);
Upvotes: 6
Reputation: 4014
After reading the Node Redis source code, I found that all methods accept an arbitrary number of arguments. When an error about incorrect number of arguments is generated, this is generated by Redis not the node module.
My early attempts to supply multiple arguments were because I only had Redis 2.2.x installed, where SET only accepts the NX and EX arguments with 2.6.12.
So with Redis 2.6.12 installed, the follow method calls will work with node redis to set a variable if it doesn't exist and set it to expire after 5 minutes:
$client->set('hello', 'world', 'NX', 'EX', 300, function(err, reply) {...});
$client->set(['hello', 'world', 'NX', 'EX', 300], function(err, reply) {...});
Upvotes: 50
Reputation: 2175
You can use a Lua script to make your own setnex
command. All Lua scripts run atomically so you do not have to worry about other clients changing data that you have already read in the script.
-- setnex.lua
local key = ARGV[1]
local expiry = ARGV[2]
local value = ARGV[3]
local reply = redis.call("SETNX", key, value)
if 1 == reply then
redis.call("EXPIRE", key, expiry)
end
return reply
You can call it from node_redis like this:
client.eval(setnex_lua, 0, "mykey", 10, "myvalue", function (err, res) {
console.dir(err);
console.dir(res);
});
Upvotes: 6