diff --git a/Gemfile.lock b/Gemfile.lock index 5047312..27f98c7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - resque-cleaner (0.4.1) + resque-cleaner (0.5) resque GEM @@ -54,4 +54,4 @@ DEPENDENCIES timecop BUNDLED WITH - 2.4.14 + 2.4.18 diff --git a/lib/resque_cleaner.rb b/lib/resque_cleaner.rb index 4a8148b..de1cd8a 100644 --- a/lib/resque_cleaner.rb +++ b/lib/resque_cleaner.rb @@ -52,7 +52,7 @@ def stats_by_date(&block) def stats_by_class(&block) jobs, stats = select(&block), {} jobs.each do |job| - klass = job["payload"] && job["payload"]["class"] ? job["payload"]["class"] : "UNKNOWN" + klass = job.klass_name stats[klass] ||= 0 stats[klass] += 1 end @@ -153,7 +153,7 @@ def clear_stale c end - # Exntends job(Hash instance) with some helper methods. + # Extends job(Hash instance) with some helper methods. module FailedJobEx # Returns true if the job has been already retried. Otherwise returns # false. @@ -180,11 +180,7 @@ def after?(time) # Returns true if the class of the job matches. Otherwise returns false. def klass?(klass_or_name) - if self["payload"] && self["payload"]["class"] - self["payload"]["class"] == klass_or_name.to_s - else - klass_or_name=="UNKNOWN" - end + klass_name == klass_or_name.to_s end # Returns true if the exception raised by the failed job matches. Otherwise returns false. @@ -196,6 +192,12 @@ def exception?(exception) def queue?(queue) self["queue"] == queue.to_s end + + def klass_name + @klass_name ||= (self.dig("payload", "args", 0).is_a?(Hash) && self.dig("payload", "args", 0, "job_class")) || + self.dig("payload", "class") || + "UNKNOWN" + end end # Through the Limiter class, you accesses only the last x(default 1000) diff --git a/lib/resque_cleaner/server.rb b/lib/resque_cleaner/server.rb index 855b485..8e326bc 100644 --- a/lib/resque_cleaner/server.rb +++ b/lib/resque_cleaner/server.rb @@ -98,7 +98,8 @@ def exception_filter(id, name, exceptions, value) end def show_job_args(args) - Array(args).map { |a| a.inspect }.join("\n") + arguments = (args[0].is_a?(Hash) && args.dig(0, "arguments")) || args + Array(arguments).map { |a| a.inspect }.join("\n") end def text_filter(id, name, value) @@ -118,7 +119,7 @@ def text_filter(id, name, value) @total = Hash.new(0) @jobs.each do |job| payload = job["payload"] || {} - klass = payload["class"] || 'UNKNOWN' + klass = job.klass_name exception = job["exception"] || 'UNKNOWN' failed_at = Time.parse job["failed_at"] @stats[:klass][klass] ||= Hash.new(0) @@ -230,7 +231,7 @@ def build_urls f: @from, t: @to, regex: @regex - }.map {|key,value| "#{key}=#{URI.encode(value.to_s)}"}.join("&") + }.map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&") @list_url = "cleaner_list?#{params}" @dump_url = "cleaner_dump?#{params}" diff --git a/lib/resque_cleaner/server/views/_stats.erb b/lib/resque_cleaner/server/views/_stats.erb index 05bafb7..ee451f3 100644 --- a/lib/resque_cleaner/server/views/_stats.erb +++ b/lib/resque_cleaner/server/views/_stats.erb @@ -10,7 +10,7 @@ <% @stats[type.to_sym].each do |field,count| %> - <% filter = "#{q}=#{URI.encode(field)}" %> + <% filter = "#{q}=#{CGI.escape(field)}" %> <%= field %> <%= count[:total] %> diff --git a/lib/resque_cleaner/server/views/cleaner_list.erb b/lib/resque_cleaner/server/views/cleaner_list.erb index f38eaa8..9f168c2 100644 --- a/lib/resque_cleaner/server/views/cleaner_list.erb +++ b/lib/resque_cleaner/server/views/cleaner_list.erb @@ -89,7 +89,7 @@ <% end %>
Class
-
<%= job['payload'] ? job['payload']['class'] : 'nil' %>
+
<%= job.klass_name %>
Arguments
<%=h job['payload'] ? show_job_args(job['payload']['args']) : 'nil' %>
Exception
diff --git a/resque-cleaner.gemspec b/resque-cleaner.gemspec index c4e0195..428c81c 100644 --- a/resque-cleaner.gemspec +++ b/resque-cleaner.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "resque-cleaner" - s.version = "0.4.1" + s.version = "0.5" s.date = Time.now.strftime('%Y-%m-%d') s.summary = "Resque plugin cleaning up failed jobs." s.homepage = "https://github.com/jobscore/resque-cleaner" diff --git a/test/resque_web_test.rb b/test/resque_web_test.rb index f2cebce..f35dcfb 100644 --- a/test/resque_web_test.rb +++ b/test/resque_web_test.rb @@ -42,6 +42,13 @@ def setup_some_failed_jobs assert last_response.ok?, last_response.errors end + it '#cleaner_list shows ActiveJob failed jobs properly formated' do + add_activejob_failure + + get "/cleaner_list", :c => "ActiveJobGoodJob" + assert last_response.body.include?("ActiveJobGoodJob") + end + it '#cleaner_list shows the failed jobs' do get "/cleaner_list" assert last_response.body.include?('BadJob') diff --git a/test/test_helper.rb b/test/test_helper.rb index 698ac82..5f9c727 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -129,3 +129,32 @@ def add_empty_payload_failure data = Resque.encode(data) Resque.redis.rpush(:failed, data) end + +def add_activejob_failure + data = { + :failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"), + :payload => { + :class => "ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper", + :args => [ + :job_class => "ActiveJobGoodJob", + :job_id => "0bc036ab-32c0-4ad0-9138-abdfb06658c4", + :provider_job_id => nil, + :queue_name => "download_scrape_job", + :priority => nil, + :arguments => [:good_job], + :executions => 0, + :exception_executions => {}, + :locale => "en", + :timezone => "UTC", + :enqueued_at => "2020-10-13T16:37:18Z" + ] + }, + :exception => "Resque::DirtyExit", + :error => "Resque::DirtyExit", + :backtrace => [], + :worker => "worker", + :queue => "queue" + } + data = Resque.encode(data) + Resque.redis.rpush(:failed, data) +end