Ну, так как никто не может мне помочь, вот «тупое» решение в псевдокоде.
Получить случайный элемент:
function maybe_get_next_item()
item_name = SRANDMEMBER "items-set"
item_key = "items:" + item_name
new_item_count = DECR (item_key)
if new_item_count < 0 then
LOCK -- As explained in SETNX docs
new_item_count = GET (item_key) -- More added while we were locking?
if new_item_count and new_item_count < 0 then
SREM (item_name) -- No, expire it
end
UNLOCK
end
if new_item_count and new_item_count >= 0 then
return item_name
end
return false -- this item not found
end
function get_next_item()
item_name = maybe_get_next_item()
while not item_name and (SCARD "items-set" > 0) do
item_name = maybe_get_next_item()
end
return item_name -- false if all items are expended
end
Вставить новые элементы
function insert_items(item_name, amount)
LOCK -- As explained in SETNX docs
SADD "items-set" (item_name)
INCRBY ("items:" + item_name) amount
UNLOCK
end
Пожалуйста, предложите лучшее решение, если оно существует, я все еще ругаю Redis и могу пропустить что-то очевидное.
Я подозреваю, что LOCK
/ UNLOCK
в insert_items()
может быть лишним и может быть заменен на MULTI
/ EXEC
, но я думаю, что это необходимо для LOCK
/ UNLOCK
в maybe_get_next_item()
для правильной работы (которую я не знаю, как заменить на MULTI
/ EXEC
) ...