2012-04-23 12 views
25

Używam pracowników Resque do przetwarzania zadania w kolejce, mam dużą liczbę zadań> 1M w kolejce i mam niektóre zadania, które muszę usunąć (dodane przez błąd). Skrzyżowanie kolejki z zadaniami nie było łatwym zadaniem, więc wyczyszczenie kolejki za pomocą narzędzia resque-web i ponowne dodanie poprawnych zadań nie jest dla mnie opcją.Jak mogę usunąć określone zadania z kolejki Resque bez usuwania całej kolejki?

Doceń wszelkie porady. Dzięki!

+0

Znalazłeś rozwiązanie tego? Czy używanie niszczenia było bardzo powolne? –

Odpowiedz

21

W źródłach Resque za (klasa Job) istnieje taki sposób, że to, co trzeba :)

# Removes a job from a queue. Expects a string queue name, a 
# string class name, and, optionally, args. 
# 
# Returns the number of jobs destroyed. 
# 
# If no args are provided, it will remove all jobs of the class 
# provided. 
# 
# That is, for these two jobs: 
# 
# { 'class' => 'UpdateGraph', 'args' => ['defunkt'] } 
# { 'class' => 'UpdateGraph', 'args' => ['mojombo'] } 
# 
# The following call will remove both: 
# 
# Resque::Job.destroy(queue, 'UpdateGraph') 
# 
# Whereas specifying args will only remove the 2nd job: 
# 
# Resque::Job.destroy(queue, 'UpdateGraph', 'mojombo') 
# 
# This method can be potentially very slow and memory intensive, 
# depending on the size of your queue, as it loads all jobs into 
# a Ruby array before processing. 
def self.destroy(queue, klass, *args) 
+0

Jeśli używasz ActiveJob, 'Resque :: Job.destroy' nie będzie pomocne, sprawdź tę odpowiedź: http://stackoverflow.com/questions/35589052/activejob-with-resque-enqueuing-jobs -with-uninteded-arguments/40066148 # 40066148 – Jared

18

Aby usunąć konkretne zadanie z kolejki można użyć metody niszczenia. Jest bardzo łatwy w użyciu, Na przykład, jeśli chcesz usunąć zadanie z klasy Post i id x, który jest w kolejce o nazwie queue1 Można zrobić tak ..

Resque::Job.destroy(queue1, Post, 'x') 

Jeśli chcesz usunąć wszystkie zadania o szczególnym rodzaju z kolejki można użyć

Resque::Job.destroy(QueueName, ClassName) 

można znaleźć to dokumentacja w

http://www.rubydoc.info/gems/resque/Resque%2FJob.destroy

0

Powyższe rozwiązania działają świetnie, jeśli znasz wszystkie argumenty przekazane do pracy. Jeśli masz sytuację, w której wiesz trochę argumentów przekazanych do pracy poniższy skrypt zadziała:

queue_name = 'a_queue' 
jobs = Resque.data_store.peek_in_queue(queue_name, 0, 500_000); 
deleted_count = 0 

jobs.each do |job| 
    decoded_job = Resque.decode(job) 
    if decoded_job['class'] == 'CoolJob' && decoded_job['args'].include?('a_job_argument') 
    Resque.data_store.remove_from_queue(queue_name, job) 
    deleted_count += 1 
    puts "Deleted!" 
    end 
end 

puts deleted_count