I ran into this problem when adding work tasks to the queue because I wanted to avoid adding a lot of duplicate tasks. It would be nice to use the Redis suite (as many have suggested), but the Redis collections do not have a "blocking pop-up window" such as BRPOPLPUSH, so they are not suitable for task queues.
So here is my slightly imperfect solution (in Python):
def pushOnlyNewItemsToList(redis, list_name, items): """ Adds only the items that aren't already in the list. Though if run simultaneously in multiple threads, there still a tiny chance of adding duplicate items. O(n) on the size of the list.""" existing_items = set(redis.lrange(list_name,0,-1)) new_items = set(items).difference(existing_items) if new_items: redis.lpush(list_name, *new_items)
Pay attention to the warnings in the documentation line.
If you really need to ensure that there are no duplicates, the alternative is to run LREM, LPUSH inside the Redis pipeline, as in 0xAffe's answer. This approach causes less network traffic, but has the disadvantage of reordering the list. This is probably the best general answer if you don't care about the order of the lists.
source share