2017-03-02 1 views
0

J'ai un cas d'utilisation où je voudrais effacer certains travaux sidekiq quand un événement se produit pour un utilisateur à l'avenir. Une manière de le faire est de stocker le job_ids quelque part (disons redis), puis de rechercher et de supprimer des tâches en utilisant cela. Mais alors je dois le stocker dans redis, et rechercher linéairement parmi tous les travaux dans la file d'attente.Marquage d'un travail dans sidekiq pour une recherche rapide et suppression à l'avenir

Une autre méthode consiste à ajouter un argument supplémentaire dans le worker. Puis recherchez en utilisant cela et supprimez.

Sidekiq::ScheduledSet.new.find {|j| j.queue == 'my_queue' && j.args[0] == "my_tag_user_id"}.map(&:delete) 

De cette façon, au moins, je n'ai pas à m'inquiéter de stocker des ID de travail dans redis. Mais je ne ferai pas la recherche plus rapidement et me semble un peu comme une solution hacky.

J'ai besoin de suggestions sur ce qui peut être le meilleur moyen d'étiqueter certaines tâches pour un utilisateur donné dans sidekiq, puis de les rechercher rapidement plus tard pour les supprimer.

Répondre

0

Les structures de données internes de Sidekiq ne sont pas optimisées pour ce type d'opération. Au lieu de cela, créez un ID de transaction pour les travaux associés à l'utilisateur et stockez-le dans votre base de données.

tid = SecureRandom.hex(16) 
user.update_column(:tid, tid) 
10.times { SomeWorker.perform_async(user.id) } 

Lorsque l'événement futur arrive, définir un indicateur dans Redis qui signale devraient être annulés tous les emplois associés à ce numéro de transaction. Lorsque les travaux sont exécutés, la première chose à faire est de vérifier s'ils ont été annulés. Si c'est le cas, ils reviennent immédiatement sans rien faire.

def perform(user_id) 
    user = User.find(user_id) 
    return if cancelled?(user.tid) 
    do_stuff 
end 
+0

Pourquoi avoir besoin d'une colonne tid. Si je vais utiliser redis comme stockage, je peux directement stocker comme clé pointant vers une liste d'identifiants de travail à supprimer en tant que valeur. Et ensuite, récupérez les identifiants de travail à partir de Redis lorsqu'un événement se produit et supprimez le travail en utilisant les identifiants de travail. – rohan

+0

Je suis d'accord avec vous quand même, que sidekiq n'est pas optimisé pour de telles opérations. Pour l'instant, je vais avec la dernière approche mentionnée dans la question en passant un argument supplémentaire et en le traitant comme une étiquette. J'ai créé une file d'attente séparée pour ce cas d'utilisation, juste pour accélérer la recherche. – rohan

+0

La suppression d'un travail par JID depuis Redis est parfois très lente. Ne fais pas ça. Oui, vous pouvez stocker les éléments TID dans Redis, pas la base de données, si vous le souhaitez. –