3 | There are more than <%= @cleaner.limiter.maximum%> jobs. ResqueCleaner handles only recent <%= @cleaner.limiter.maximum %> jobs. See the Limiter section on README for more detail.
4 |
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Tatsuya Ono
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/resque-cleaner.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |s|
2 | s.name = "resque-cleaner"
3 | s.version = "0.4.1"
4 | s.date = Time.now.strftime('%Y-%m-%d')
5 | s.summary = "Resque plugin cleaning up failed jobs."
6 | s.homepage = "https://github.com/ono/resque-cleaner"
7 | s.email = "ononoma@gmail.com"
8 | s.authors = [ "Tatsuya Ono" ]
9 | s.license = "MIT"
10 | s.required_ruby_version = '>= 1.9.3'
11 |
12 | s.files = %w( README.md CHANGELOG.md Rakefile LICENSE )
13 | s.files += Dir.glob("lib/**/*")
14 | s.files += Dir.glob("test/**/*")
15 |
16 | s.require_paths = ["lib"]
17 |
18 | s.extra_rdoc_files = [ "LICENSE", "README.md", "CHANGELOG.md" ]
19 | s.rdoc_options = ["--charset=UTF-8"]
20 |
21 | s.add_dependency "resque"
22 |
23 | s.add_development_dependency "minitest", "~> 5.0"
24 | s.add_development_dependency "rack-test", "~> 0.6.0"
25 |
26 | s.description = <
2 |
3 |
<%= type.gsub('klass','class').capitalize %>
4 |
Failed
5 |
In last 1 hour
6 |
In last 3 hours
7 |
In last 24 hours
8 |
In last 3 days
9 |
In last 7 days
10 |
11 | <% @stats[type.to_sym].each do |field,count| %>
12 |
54 |
55 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.4.1 (2018-01-25)
2 |
3 | * Remove Requeue version lock (#46)
4 |
5 | ## 0.4.0 (2017-11-20)
6 |
7 | * Render CSS as ERB partial to make Rails 5 compatible (#45)
8 |
9 | ## 0.3.2 (2016-03-09)
10 |
11 | * Handle failure JSON with nil on payload safely (#40)
12 |
13 | ## 0.3.1 (2016-01-28)
14 |
15 | * Bug fix: fix the issue regex is not applied on bulk clearance (#36)
16 |
17 | ## 0.3.0 (2014-05-27)
18 |
19 | * Search by regex (#27)
20 | * Show stats by exception (#29)
21 | * Stop supporting ruby 1.8.x and 1.9.2
22 | * Escape query parameters (#30)
23 |
24 | ## 0.2.12 (2013-12-03)
25 |
26 | * Remove Resque::Helpers include (#23)
27 | * Tweak Gemspec (#24)
28 | * Don't use yaml format to show arguments
29 | * Tweak README
30 |
31 | ## 0.2.11 (2013-07-19)
32 |
33 | * Use transaction for retry-and-clear (#22).
34 | * Fix for CI
35 |
36 | ## 0.2.10 (2012-10-15)
37 |
38 | * Bug fix: use URL helper to support resque-web which is not hosted under '/'.
39 |
40 | ## 0.2.9 (2012-05-10)
41 |
42 | * Make limiter configurable on resque-web.
43 |
44 | ## 0.2.8 (2012-03-19)
45 |
46 | * UI tweak (#15)
47 |
48 | ## 0.2.7 (2012-01-17)
49 |
50 | * Support Travis CI
51 | * Support failure jobs without payload information (#11).
52 |
53 | ## 0.2.6 (2011-08-23)
54 |
55 | * Follow the latest resque for date format.
56 |
57 | ## 0.2.5 (2011-05-05)
58 |
59 | * BUGFIX: Pagination has been broken.
60 | * Dump a list as JSON format.
61 |
62 | ## 0.2.4 (2011-04-19)
63 |
64 | * BUGFIX: "Select All" ignores exception filter.
65 |
66 | ## 0.2.3 (2011-04-11)
67 |
68 | * Exception filter.
69 |
70 | ## 0.2.2 (2011-04-07)
71 |
72 | * Changed a way to load yajl/json\_gem.
73 |
74 | ## 0.2.1 (2011-04-06)
75 |
76 | * BUGFIX: Bulk action didn't work properly when you select all jobs.
77 | * Removed absolute paths from html.
78 |
79 | ## 0.2.0 (2011-04-06)
80 |
81 | * Extended with resque-web
82 |
83 | ## 0.1.1 (2010-12-30)
84 |
85 | * Fixed for ruby 1.9.2
86 | * Fixed a bug on #retried? method
87 |
88 | ## 0.1.0 (2010-11-24)
89 |
90 | * First official release
91 |
92 |
93 |
--------------------------------------------------------------------------------
/examples/failure_job.json:
--------------------------------------------------------------------------------
1 | {"failed_at": "2009/03/13 00:00:00",
2 | "payload": {"args": ["Johnson"], "class": "BadJob"},
3 | "queue": "jobs",
4 | "worker": "localhost:7327:jobs,jobs2",
5 | "exception": "RuntimeError",
6 | "error": "Bad job, Johnson",
7 | "backtrace":
8 | ["./test/test_helper.rb:108:in `perform'",
9 | "/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/job.rb:133:in `perform'",
10 | "/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:157:in `perform'",
11 | "/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:124:in `work'",
12 | "/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:110:in `loop'",
13 | "/opt/local/lib/ruby/gems/1.8/gems/resque-1.10.0/lib/resque/worker.rb:110:in `work'",
14 | "test/resque_cleaner_test.rb:9:in `create_and_process_jobs'",
15 | "/opt/local/lib/ruby/gems/1.8/gems/timecop-0.3.5/lib/timecop/timecop.rb:91:in `travel'",
16 | "/opt/local/lib/ruby/gems/1.8/gems/timecop-0.3.5/lib/timecop/timecop.rb:49:in `send'",
17 | "/opt/local/lib/ruby/gems/1.8/gems/timecop-0.3.5/lib/timecop/timecop.rb:49:in `freeze'",
18 | "test/resque_cleaner_test.rb:5:in `create_and_process_jobs'",
19 | "test/resque_cleaner_test.rb:28:in `setup'",
20 | "/opt/local/lib/ruby/1.8/test/unit/testcase.rb:77:in `run'",
21 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'",
22 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'",
23 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'",
24 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'",
25 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'",
26 | "/opt/local/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'",
27 | "/opt/local/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'",
28 | "/opt/local/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:67:in `start_mediator'",
29 | "/opt/local/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:41:in `start'",
30 | "/opt/local/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:29:in `run'",
31 | "/opt/local/lib/ruby/1.8/test/unit/autorunner.rb:216:in `run'",
32 | "/opt/local/lib/ruby/1.8/test/unit/autorunner.rb:12:in `run'",
33 | "./test/test_helper.rb:41",
34 | "test/resque_cleaner_test.rb:3"]
35 | }
36 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Mostly copied from Resque in order to have similar test environment.
2 | # https://github.com/defunkt/resque/blob/master/test/test_helper.rb
3 |
4 | dir = File.dirname(File.expand_path(__FILE__))
5 | $LOAD_PATH.unshift dir + '/../lib'
6 | $TESTING = true
7 | require 'rubygems'
8 | require 'minitest'
9 | require 'minitest/spec'
10 | require 'minitest/autorun'
11 | require 'resque'
12 | require 'timecop'
13 |
14 | begin
15 | require 'leftright'
16 | rescue LoadError
17 | end
18 | require 'resque'
19 | require 'resque_cleaner'
20 |
21 | $TEST_PID = Process.pid
22 |
23 | #
24 | # make sure we can run redis
25 | #
26 |
27 | if !system("which redis-server")
28 | puts '', "** can't find `redis-server` in your path"
29 | puts "** try running `sudo rake install`"
30 | abort ''
31 | end
32 |
33 |
34 | #
35 | # start our own redis when the tests start,
36 | # kill it when they end
37 | #
38 | MiniTest.after_run {
39 | if Process.pid == $TEST_PID
40 | processes = `ps -A -o pid,command | grep [r]edis-test`.split($/)
41 | pids = processes.map { |process| process.split(" ")[0] }
42 | puts "Killing test redis server..."
43 | pids.each { |pid| Process.kill("TERM", pid.to_i) }
44 | dump = "test/dump.rdb"
45 | File.delete(dump) if File.exist?(dump)
46 | end
47 | }
48 |
49 | puts "Starting redis for testing at localhost:9736..."
50 | `redis-server #{dir}/redis-test.conf`
51 | Resque.redis = 'localhost:9736'
52 |
53 |
54 | ##
55 | # Helper to perform job classes
56 | #
57 | module PerformJob
58 | def perform_job(klass, *args)
59 | resque_job = Resque::Job.new(:testqueue, 'class' => klass, 'args' => args)
60 | resque_job.perform
61 | end
62 | end
63 |
64 | #
65 | # fixture classes
66 | #
67 |
68 | class SomeJob
69 | def self.perform(repo_id, path)
70 | end
71 | end
72 |
73 | class SomeIvarJob < SomeJob
74 | @queue = :ivar
75 | end
76 |
77 | class SomeMethodJob < SomeJob
78 | def self.queue
79 | :method
80 | end
81 | end
82 |
83 | class BadJob
84 | def self.perform(name=nil)
85 | msg = name ? "Bad job, #{name}" : "Bad job!"
86 | raise msg
87 | end
88 | end
89 |
90 | class GoodJob
91 | def self.perform(name)
92 | "Good job, #{name}"
93 | end
94 | end
95 |
96 | class BadJobWithSyntaxError
97 | def self.perform
98 | raise SyntaxError, "Extra Bad job!"
99 | end
100 | end
101 |
102 | #
103 | # helper methods
104 | #
105 |
106 | def create_and_process_jobs(queue,worker,num,date,job,*args)
107 | Timecop.freeze(date) do
108 | num.times do
109 | Resque::Job.create(queue, job, *args)
110 | end
111 | worker.work(0)
112 | end
113 | end
114 |
115 | def queue_size(*queues)
116 | queues.inject(0){|sum,queue| sum + Resque.size(queue).to_i}
117 | end
118 |
119 | def add_empty_payload_failure
120 | data = {
121 | :failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"),
122 | :payload => nil,
123 | :exception => "Resque::DirtyExit",
124 | :error => "Resque::DirtyExit",
125 | :backtrace => [],
126 | :worker => "worker",
127 | :queue => "queue"
128 | }
129 | data = Resque.encode(data)
130 | Resque.redis.rpush(:failed, data)
131 | end
132 |
--------------------------------------------------------------------------------
/test/redis-test.conf:
--------------------------------------------------------------------------------
1 | # Redis configuration file example
2 |
3 | # By default Redis does not run as a daemon. Use 'yes' if you need it.
4 | # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5 | daemonize yes
6 |
7 | # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8 | # You can specify a custom pid file location here.
9 | pidfile ./test/redis-test.pid
10 |
11 | # Accept connections on the specified port, default is 6379
12 | port 9736
13 |
14 | # If you want you can bind a single interface, if the bind option is not
15 | # specified all the interfaces will listen for connections.
16 | #
17 | # bind 127.0.0.1
18 |
19 | # Close the connection after a client is idle for N seconds (0 to disable)
20 | timeout 300
21 |
22 | # Save the DB on disk:
23 | #
24 | # save
25 | #
26 | # Will save the DB if both the given number of seconds and the given
27 | # number of write operations against the DB occurred.
28 | #
29 | # In the example below the behaviour will be to save:
30 | # after 900 sec (15 min) if at least 1 key changed
31 | # after 300 sec (5 min) if at least 10 keys changed
32 | # after 60 sec if at least 10000 keys changed
33 | save 900 1
34 | save 300 10
35 | save 60 10000
36 |
37 | # The filename where to dump the DB
38 | dbfilename dump.rdb
39 |
40 | # For default save/load DB in/from the working directory
41 | # Note that you must specify a directory not a file name.
42 | dir ./test/
43 |
44 | # Set server verbosity to 'debug'
45 | # it can be one of:
46 | # debug (a lot of information, useful for development/testing)
47 | # notice (moderately verbose, what you want in production probably)
48 | # warning (only very important / critical messages are logged)
49 | loglevel debug
50 |
51 | # Specify the log file name. Also 'stdout' can be used to force
52 | # the demon to log on the standard output. Note that if you use standard
53 | # output for logging but daemonize, logs will be sent to /dev/null
54 | logfile stdout
55 |
56 | # Set the number of databases. The default database is DB 0, you can select
57 | # a different one on a per-connection basis using SELECT where
58 | # dbid is a number between 0 and 'databases'-1
59 | databases 16
60 |
61 | ################################# REPLICATION #################################
62 |
63 | # Master-Slave replication. Use slaveof to make a Redis instance a copy of
64 | # another Redis server. Note that the configuration is local to the slave
65 | # so for example it is possible to configure the slave to save the DB with a
66 | # different interval, or to listen to another port, and so on.
67 |
68 | # slaveof
69 |
70 | ################################## SECURITY ###################################
71 |
72 | # Require clients to issue AUTH before processing any other
73 | # commands. This might be useful in environments in which you do not trust
74 | # others with access to the host running redis-server.
75 | #
76 | # This should stay commented out for backward compatibility and because most
77 | # people do not need auth (e.g. they run their own servers).
78 |
79 | # requirepass foobared
80 |
81 | ################################### LIMITS ####################################
82 |
83 | # Set the max number of connected clients at the same time. By default there
84 | # is no limit, and it's up to the number of file descriptors the Redis process
85 | # is able to open. The special value '0' means no limts.
86 | # Once the limit is reached Redis will close all the new connections sending
87 | # an error 'max number of clients reached'.
88 |
89 | # maxclients 128
90 |
91 | # Don't use more memory than the specified amount of bytes.
92 | # When the memory limit is reached Redis will try to remove keys with an
93 | # EXPIRE set. It will try to start freeing keys that are going to expire
94 | # in little time and preserve keys with a longer time to live.
95 | # Redis will also try to remove objects from free lists if possible.
96 | #
97 | # If all this fails, Redis will start to reply with errors to commands
98 | # that will use more memory, like SET, LPUSH, and so on, and will continue
99 | # to reply to most read-only commands like GET.
100 | #
101 | # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
102 | # 'state' server or cache, not as a real DB. When Redis is used as a real
103 | # database the memory usage will grow over the weeks, it will be obvious if
104 | # it is going to use too much memory in the long run, and you'll have the time
105 | # to upgrade. With maxmemory after the limit is reached you'll start to get
106 | # errors for write operations, and this may even lead to DB inconsistency.
107 |
108 | # maxmemory
109 |
110 | ############################### ADVANCED CONFIG ###############################
111 |
112 | # Glue small output buffers together in order to send small replies in a
113 | # single TCP packet. Uses a bit more CPU but most of the times it is a win
114 | # in terms of number of queries per second. Use 'yes' if unsure.
115 | #glueoutputbuf yes
116 |
--------------------------------------------------------------------------------
/lib/resque_cleaner/server/views/cleaner_list.erb:
--------------------------------------------------------------------------------
1 | <%= erb File.read(ResqueCleaner::Server.erb_path("_cleaner_styles.erb")) %>
2 |
3 |
4 |