За да реализирам проста опашка в redis, която може да се използва за повторно изпращане на сривани задания, бих опитал нещо подобно:
- 1 списък „up_for_grabs“
- 1 списък „being_worked_on“
- автоматично изтичащи ключалки
работник, който се опитва да грабне работа, би направил нещо подобно:
timeout = 3600
#wrap this in a transaction so our cleanup wont kill the task
#Move the job away from the queue so nobody else tries to claim it
job = RPOPLPUSH(up_for_grabs, being_worked_on)
#Set a lock and expire it, the value tells us when that job will time out. This can be arbitrary though
SETEX('lock:' + job, Time.now + timeout, timeout)
#our application logic
do_work(job)
#Remove the finished item from the queue.
LREM being_worked_on -1 job
#Delete the item's lock. If it crashes here, the expire will take care of it
DEL('lock:' + job)
И от време на време бихме могли просто да вземем нашия списък и да проверим дали всички работни места, които са там, всъщност имат заключване. Ако открием работа, която НЯМА заключване, това означава, че е изтекла и нашият работник вероятно се е сринал. този случай ще изпратим отново.
Това би бил псевдокодът за това:
loop do
items = LRANGE(being_worked_on, 0, -1)
items.each do |job|
if !(EXISTS("lock:" + job))
puts "We found a job that didn't have a lock, resubmitting"
LREM being_worked_on -1 job
LPUSH(up_for_grabs, job)
end
end
sleep 60
end