shapeare
shapeare

Reputation: 4233

How to hold a lock to redis?

I have the following NodeJS code that initialize a list only if the list doesn't exist.

if (redisClient.lLen('mylist') === 0) {
    let initialVal = Array(100).fill(-1)
    await redisClient.rPush('mylist', initialVal)
}

If the above code is running at the same time by multiple instances, then due to race conditions await redisClient.rPush('mylist', initialVal) may run multiple times.

I only want the above code to run once by one of the NodeJS instances to initialize the list. How can I make the above code an atomic operation?

Answer

I formatted the answer given by Stephen Jennings (Thank you!)

redisClient.EVAL(`
    if redis.call("LLEN", "mylist") == 0
    then
    for i = 1,100,1 do
        redis.call("RPUSH", "mylist", "-1")
    end
    end
`)

Upvotes: 1

Views: 399

Answers (2)

Stephen Jennings
Stephen Jennings

Reputation: 13234

Use a Lua script to do the check and inserts atomically.

redisClient.EVAL(`
if redis.call(“LLEN”, “mylist”) == 0
  for i = 1,100,1
    redis.call(”RPUSH”, ”mylist”, ”-1”)
  end
end
`)

Upvotes: 3

namizaru
namizaru

Reputation: 824

While I don't fully understand the use case, you might want to look into the RPUSHX command as a way to ensure you only add to a list that exists.

Upvotes: 1

Related Questions