För att realisera en enkel kö i redis som kan användas för att skicka in kraschade jobb igen skulle jag prova något i stil med detta:
- 1 lista "up_for_grabs"
- 1 lista "being_worked_on"
- automatiskt upphörande lås
en arbetare som försöker ta ett jobb skulle göra något sånt här:
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)
Och då och då kunde vi bara ta vår lista och kontrollera att alla jobb som finns där faktiskt har ett lås. Om vi hittar några jobb som INTE har något lås betyder det att det har gått ut och att vår arbetare förmodligen kraschade. detta ärende skulle vi skicka in igen.
Detta skulle vara pseudokoden för det:
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