redis: atomic LPOP and SADD possible?

list, queue, redis, set

Solution

Why do you want your "in progress" collection be a Set? You could simply use a List for the in progress items.

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

Atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination

If you do want to use a Set for your in progress items, you will have to use a lua script and call it using eval.

Problem

Is there anyway to atomically pop an item from a list and add it to a set? My case scenario is that I have a "work queue" list of unique items, and I want to track what's being worked on in a "in progress" set. This would also allow the items in the "in progress" set to be re-queued if my worker process crashes while working on an item. I'd prefer it to be atomic so that anything popped from the list will always be in the set. I just can't figure out how to do this with MULTI/EXEC, ie: ``` redis> MULTI OK redis> LPOP workqueue "foobar" redis> SADD inprog "foobar" redis> EXEC ```

Original source