Mam aplikację, która korzysta z Sidekiq. Proces serwera sieciowego czasami umieszcza zadanie w Sidekiq, ale niekoniecznie będzie on działał. Czy istnieje narzędzie, które mógłbym wywołać z konsoli Rails, które spowodowałoby wycofanie jednego zadania z kolejki Redis i uruchomienie odpowiedniego pracownika Sidekiq?Jak ręcznie uruchomić zadanie Sidekiq
Odpowiedz
Możesz to zrobić, używając klasy Sidekiq::Queue
w konsoli Rails.
Aby uruchomić zadanie:
queue = Sidekiq::Queue.new # access the default queue
job = queue.first # get the most recent job
klass, method, args = YAML.load(queue.first.args[0]) # unserialize
klass.send(method, *args) # run the code that the job would perform
Należy pamiętać, że to nie będzie miało wpływu na kolejkę lub statystyki obsługiwane przez Sidekiq::Stats.new
.
> Sidekiq::Stats.new
=> #<Sidekiq::Stats:0x007fe7c74db8e8 @stats={:processed=>0, :failed=>0, :scheduled_size=>0, :retry_size=>0, :dead_size=>0, :processes_size=>1, :default_queue_latency=>1056925.2464652061, :workers_size=>0, :enqueued=>1}>
Aby usunąć zadanie po prostu dotknął z przodu kolejki:
> queue.first.delete
=> true
> Sidekiq::Stats.new
=> #<Sidekiq::Stats:0x007fe7c74db8e8 @stats={:processed=>0, :failed=>0, :scheduled_size=>0, :retry_size=>0, :dead_size=>0, :processes_size=>1, :default_queue_latency=>1056925.2464652061, :workers_size=>0, :enqueued=>0}>
Jeśli praca jest programem pocztowym, nie zapomnij dodać '.deliver' w' klass.send (method, * args) ' –
To nie działa. 'queue.first.args [0]' jest hasłem, więc dlaczego miałbym wywołać na nim 'YAML.load'? Ponadto skrót nie zawiera niczego, co odpowiada krotce "klass, method, args". –
Jak wspomniano wcześniej, argumenty są hash, więc to nie działa – Mike
nie będę próbować włamać API sidekiq do uruchomienia zadania ręcznie, ponieważ mogłoby to zostawić jakiś niepożądany wewnętrzny stan, ale wierzę, że poniższy kod zadziała
# Fetch the Queue
queue = Sidekiq::Queue.new # default queue
# OR
# queue = Sidekiq::Queue.new(:my_queue_name)
# Fetch the job
# job = queue.first
# OR
job = queue.find do |job|
meta = job.args.first
# => {"job_class" => "MyJob", "job_id"=>"1afe424a-f878-44f2-af1e-e299faee7e7f", "queue_name"=>"my_queue_name", "arguments"=>["Arg1", "Arg2", ...]}
meta['job_class'] == 'MyJob' && meta['arguments'].first == 'Arg1'
end
# Removes from queue so it doesn't get processed twice
job.delete
meta = job.args.first
klass = meta['job_class'].constantize
# => MyJob
# Performs the job without using Sidekiq's API, does not count as performed job and so on.
klass.new.perform(*meta['arguments'])
# OR
# Perform the job using Sidekiq's API so it counts as performed job and so on.
# klass.new(*meta['arguments']).perform_now
Proszę dać mi znać, jeśli to nie działa lub jeśli ktoś zna lepszy sposób to zrobić.
powiadom nas o tym gdy znasz – user1735921