Redis
 sql >> Base de données >  >> NoSQL >> Redis

File d'attente Redis avec expiration de la revendication

Pour réaliser une simple file d'attente dans redis qui peut être utilisée pour resoumettre les travaux plantés, j'essaierais quelque chose comme ceci :

  • 1 liste "up_for_grabs"
  • 1 liste "être_travaillé_sur"
  • verrous à expiration automatique

un travailleur essayant de décrocher un emploi ferait quelque chose comme ceci :

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)

Et de temps en temps, nous pourrions simplement saisir notre liste et vérifier que tous les travaux qui s'y trouvent ont bien un verrou. Si nous trouvons des travaux qui N'ONT PAS de verrou, cela signifie qu'il a expiré et que notre travailleur s'est probablement écrasé. ce cas, nous le soumettrions à nouveau.

Ce serait le pseudo-code pour cela :

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