Redis: atomic LPOP and SADD possible?

Is there anyway to atomistically pull an element from the list and add it to the set?

My scenario is that I have a list of "work queues" of unique items, and I want to keep track of what is working on "in progress". It would also allow the elements "in process" to set the queue override if my workflow crashes while working on the element.

I would prefer that it be atomic, so that everything that is on the list is always in the set. I just can't figure out how to do this with MULTI / EXEC, that is:

redis> MULTI OK redis> LPOP workqueue "foobar" redis> SADD inprog "foobar" redis> EXEC 
+7
source share
2 answers

Why do you want your "in progress" collection to be Set? You can simply use the list for current items.

The RPOPLPUSH "Right Pop, Left Push" command was made specifically for this use case.

Atomically returns and deletes the last element (tail) of the list stored at the source and pushes the element into the first element (head) of the list stored in the destination

If you want to use a set for your progress elements, you will need to use a lua script and invoke it using eval .

+5
source

It seems that MULTI / EXEC will not work, because the second command depends on the return value of the first, but none of the commands are executed until EXEC is called. If you are using Redis 2.6 (currently in RC), you can use lua script via eval .

In general, I do not think that atomicity is of great concern here. In this case, there are no race conditions. The only thing that can happen is that the server crashes in the interval between the withdrawal of an element from the queue and its addition to the set, which seems unlikely.

+1
source

All Articles