resque_stuck_queue_revised 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,34 @@
1
+ require 'minitest'
2
+ require "minitest/autorun"
3
+ require 'pry'
4
+
5
+ $:.unshift(".")
6
+ require 'resque_stuck_queue'
7
+ require File.join(File.expand_path(File.dirname(__FILE__)), "resque", "set_redis_key")
8
+ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
9
+
10
+ class TestLagTime < Minitest::Test
11
+
12
+ include TestHelper
13
+
14
+ def setup
15
+ Resque::StuckQueue.config[:redis] = Redis.new
16
+ Resque::StuckQueue.redis.flushall
17
+ Resque::StuckQueue.config[:abort_on_exception] = true
18
+ Resque::StuckQueue.config[:watcher_interval] = 1
19
+ end
20
+
21
+ def test_triggers_handler_with_lagtime
22
+ Resque::StuckQueue.config[:trigger_timeout] = 2 # won't allow waiting too much and will complain (eg trigger) sooner than later
23
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
24
+ @lagtime = 0
25
+ Resque::StuckQueue.config[:triggered_handler] = proc { |queue_name, lagtime| @lagtime = lagtime }
26
+ start_and_stop_loops_after(5)
27
+
28
+ # check handler did get called
29
+ assert @lagtime > 0, "lagtime shoudl be set"
30
+ assert @lagtime < 5, "lagtime shoudl be set"
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1,96 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
2
+
3
+ class TestNamedQueues < Minitest::Test
4
+
5
+ include TestHelper
6
+
7
+ def setup
8
+ Resque::StuckQueue.config[:trigger_timeout] = 1
9
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
10
+ Resque::StuckQueue.config[:abort_on_exception] = true
11
+ Resque::StuckQueue.config[:redis] = Redis.new
12
+ Resque::StuckQueue.config[:watcher_interval] = 1
13
+ Resque::StuckQueue.redis.flushall
14
+ end
15
+
16
+ def teardown
17
+ hax_kill_resque
18
+ Resque::StuckQueue.force_stop!
19
+ Process.waitpid(@resque_pid) if @resque_pid
20
+ end
21
+
22
+ def test_no_custom_queues_defaults_to_app
23
+ puts "#{__method__}"
24
+ Resque::StuckQueue.config[:queues] = nil
25
+ start_and_stop_loops_after(2)
26
+ assert Resque::StuckQueue.heartbeat_keys.include?("app:resque-stuck-queue"), 'has global keys'
27
+ end
28
+
29
+ def test_has_custom_queues
30
+ puts "#{__method__}"
31
+ Resque::StuckQueue.config[:queues] = [:foo,:bar]
32
+ assert Resque::StuckQueue.heartbeat_keys.include?("foo:resque-stuck-queue"), 'has global keys'
33
+ end
34
+
35
+ def test_resque_enqueues_a_job_with_resqueue_running_but_on_that_queue_does_trigger
36
+ puts "#{__method__}"
37
+ Resque::StuckQueue.config[:trigger_timeout] = 2 # won't allow waiting too much and will complain (eg trigger) sooner than later
38
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
39
+ Resque::StuckQueue.config[:queues] = [:custom_queue_name]
40
+ @triggered = false
41
+ Resque::StuckQueue.config[:triggered_handler] = proc { |queue_name| @triggered = queue_name }
42
+ Resque::StuckQueue.start_in_background
43
+
44
+ # job gets enqueued successfully
45
+ @resque_pid = run_resque("no-such-jobs-for-this-queue")
46
+ sleep 2 # allow timeout to trigger
47
+
48
+ # check handler did get called
49
+ assert_equal @triggered, :custom_queue_name
50
+ end
51
+
52
+ def test_resque_enqueues_a_job_correct_queue_does_not_trigger
53
+ puts "#{__method__}"
54
+ Resque::StuckQueue.config[:trigger_timeout] = 2 # won't allow waiting too much and will complain (eg trigger) sooner than later
55
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
56
+ Resque::StuckQueue.config[:queues] = [:custom_queue_name, :diff_one]
57
+ assert Resque::StuckQueue.heartbeat_keys.include?("custom_queue_name:resque-stuck-queue"), 'has global keys'
58
+ @triggered = false
59
+ Resque::StuckQueue.config[:triggered_handler] = proc { @triggered = true }
60
+ @resque_pid = run_resque("custom_queue_name")
61
+ Resque::StuckQueue.start_in_background
62
+ sleep 2 # allow timeout to trigger
63
+
64
+ # check handler did not get called
65
+ assert_equal @triggered, false
66
+ end
67
+
68
+ def test_triggers_once_and_then_recovers
69
+ # FIXME test refactoring wrong place for this test.
70
+ puts "#{__method__}"
71
+
72
+ Resque::StuckQueue.config[:trigger_timeout] = 2
73
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
74
+ Resque::StuckQueue.config[:queues] = [:app]
75
+
76
+ @triggered = 0
77
+ @recovered = 0
78
+ Resque::StuckQueue.config[:triggered_handler] = proc { @triggered += 1 }
79
+ Resque::StuckQueue.config[:recovered_handler] = proc { @recovered += 1 }
80
+
81
+ Thread.new {
82
+ # mock a job going through after we trigger :recovered so we'll w/o doing a run_resque
83
+ Thread.current.abort_on_exception = true
84
+ sleep 3
85
+ Resque::StuckQueue.redis.set(Resque::StuckQueue.heartbeat_key_for(:app), Time.now.to_i)
86
+ }
87
+ start_and_stop_loops_after(4)
88
+
89
+ # check handler did get called ONCE
90
+ assert_equal @recovered, 1
91
+ assert_equal @triggered, 1
92
+ end
93
+
94
+ end
95
+
96
+
@@ -0,0 +1,58 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
2
+
3
+ class TestResqueStuckQueue < Minitest::Test
4
+
5
+ include TestHelper
6
+
7
+ def teardown
8
+ puts "#{__method__}"
9
+ Resque::StuckQueue.unstub(:read_from_redis)
10
+ end
11
+
12
+ def setup
13
+ puts "#{__method__}"
14
+ # clean previous test runs
15
+ Resque::StuckQueue.config[:redis] = Redis.new
16
+ Resque::StuckQueue.config[:watcher_interval] = 1
17
+ Resque::StuckQueue.redis.flushall
18
+ Resque::StuckQueue.config[:heartbeat_interval] = 1 # seconds
19
+ Resque::StuckQueue.config[:abort_on_exception] = true
20
+ end
21
+
22
+ def test_configure_heartbeat_key
23
+ puts "#{__method__}"
24
+ assert_nil Resque::StuckQueue.redis.get("it-is-configurable"), "global key should not be set"
25
+ Resque::StuckQueue.config[:heartbeat_key] = "it-is-configurable"
26
+ start_and_stop_loops_after(3)
27
+ refute_nil Resque::StuckQueue.redis.get("app:it-is-configurable"), "global key should be set"
28
+ end
29
+
30
+ def test_it_does_not_trigger_handler_if_under_max_time
31
+ puts "#{__method__}"
32
+ Resque::StuckQueue.config[:trigger_timeout] = 5
33
+ Resque::StuckQueue.stubs(:read_from_redis).returns(Time.now.to_i)
34
+
35
+ @triggered = false
36
+ Resque::StuckQueue.config[:triggered_handler] = proc { @triggered = true }
37
+ start_and_stop_loops_after(3)
38
+ assert_equal false, @triggered # "handler should not be called"
39
+ end
40
+
41
+ def test_stops_if_handler_raises
42
+ puts "#{__method__}"
43
+ Resque::StuckQueue.config[:trigger_timeout] = 1 # wait a short time, will trigger
44
+ Resque::StuckQueue.config[:abort_on_exception] = true # bubble up the raise
45
+ last_time_too_old = Time.now.to_i - Resque::StuckQueue::TRIGGER_TIMEOUT
46
+ Resque::StuckQueue.config[:triggered_handler] = proc { raise "handler had bad sad!" }
47
+ begin
48
+ start_and_stop_loops_after(4)
49
+ sleep 4
50
+ assert false, "should raise"
51
+ rescue => e
52
+ puts e.inspect
53
+ assert true, "should raise handler bad sad #{e.inspect}"
54
+ end
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,41 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
2
+
3
+ class TestYourOwnRefreshJob < Minitest::Test
4
+
5
+ include TestHelper
6
+
7
+ def setup
8
+ Resque::StuckQueue.reset!
9
+ Resque::StuckQueue.config[:trigger_timeout] = 1
10
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
11
+ Resque::StuckQueue.config[:watcher_interval] = 1
12
+ Resque::StuckQueue.config[:abort_on_exception] = true
13
+ Resque::StuckQueue.config[:heartbeat_job] = nil
14
+ Resque::StuckQueue.config[:redis] = Redis.new
15
+ Resque::StuckQueue.redis.flushall
16
+ end
17
+
18
+ def test_will_trigger_with_unrefreshing_custom_heartbeat_job
19
+ # it will trigger because the key will be unrefreshed, hence 'old' and will always trigger.
20
+ puts "#{__method__}"
21
+ Resque::StuckQueue.config[:heartbeat_job] = proc { nil } # does not refresh global key
22
+ @triggered = false
23
+ Resque::StuckQueue.config[:triggered_handler] = proc { @triggered = true }
24
+ start_and_stop_loops_after(3)
25
+ assert @triggered, "will trigger because global key will be old"
26
+ end
27
+
28
+ def test_will_fail_with_bad_custom_heartbeat_job
29
+ puts "#{__method__}"
30
+ begin
31
+ Resque::StuckQueue.config[:heartbeat_job] = proc { raise 'bad proc doc' } # does not refresh global key
32
+ @triggered = false
33
+ Resque::StuckQueue.config[:triggered_handler] = proc { @triggered = true }
34
+ start_and_stop_loops_after(3)
35
+ assert false, "should not succeed with bad refresh_job"
36
+ rescue
37
+ assert true, "will fail with bad refresh_job"
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,45 @@
1
+ # run with
2
+ # $ RESQUE_2=1 bi; RESQUE_2=1 be ruby -I. -Ilib/ test/test_resque_2.rb
3
+ if !ENV['RESQUE_2'].nil?
4
+
5
+ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
6
+
7
+ class TestResque2 < Minitest::Test
8
+
9
+ include TestHelper
10
+
11
+ def setup
12
+ assert (Resque::VERSION.match /^2\./), "must run in 2.0"
13
+ Resque.redis = Redis.new
14
+ Resque::StuckQueue.config[:redis] = Redis.new
15
+ Redis.new.flushall
16
+ end
17
+
18
+ def test_works_with_2_point_oh_do_not_trigger_because_key_is_updated
19
+
20
+ Resque::StuckQueue.config[:redis] = Redis.new
21
+
22
+ Resque::StuckQueue.config[:watcher_interval] = 1
23
+ Resque::StuckQueue.config[:heartbeat_interval] = 1
24
+ Resque::StuckQueue.config[:abort_on_exception] = true
25
+ Resque::StuckQueue.config[:trigger_timeout] = 5
26
+ Resque::StuckQueue.config[:logger] = Logger.new($stdout)
27
+ Resque::StuckQueue.config[:triggered_handler] = proc { Redis.new.incr("test-incr-key") }
28
+ Resque::StuckQueue.config[:redis] = Redis.new
29
+ Resque::StuckQueue.config[:queues] = [:app]
30
+
31
+ #binding.pry
32
+ Resque::StuckQueue.start_in_background
33
+
34
+ @r2_pid = fork { Resque::StuckQueue.config[:redis] = Redis.new ; Resque::Worker.new("*", :graceful_term => true).work ; Process.waitall }
35
+ sleep 10
36
+
37
+ # triggers once
38
+ assert_equal Redis.new.get("test-incr-key").to_i, 1
39
+ hax_kill_resque
40
+ Resque::StuckQueue.force_stop!
41
+ end
42
+
43
+ end
44
+
45
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque_stuck_queue_revised
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ platform: ruby
6
+ authors:
7
+ - Dave Kerr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis-mutex
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis-namespace
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: where the wild things are. err, when resque gets stuck
70
+ email:
71
+ - davek09@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - THOUGHTS
82
+ - lib/resque/stuck_queue.rb
83
+ - lib/resque_stuck_queue.rb
84
+ - lib/resque_stuck_queue/config.rb
85
+ - lib/resque_stuck_queue/heartbeat_job.rb
86
+ - lib/resque_stuck_queue/version.rb
87
+ - resque_stuck_queue.gemspec
88
+ - test/resque/set_redis_key.rb
89
+ - test/test_collision.rb
90
+ - test/test_config.rb
91
+ - test/test_helper.rb
92
+ - test/test_integration.rb
93
+ - test/test_lagtime.rb
94
+ - test/test_named_queues.rb
95
+ - test/test_resque_stuck_queue.rb
96
+ - test/test_set_custom_refresh_job.rb
97
+ - test/test_ver_2.rb
98
+ homepage: ''
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: fire a handler when your queues are wonky
122
+ test_files:
123
+ - test/resque/set_redis_key.rb
124
+ - test/test_collision.rb
125
+ - test/test_config.rb
126
+ - test/test_helper.rb
127
+ - test/test_integration.rb
128
+ - test/test_lagtime.rb
129
+ - test/test_named_queues.rb
130
+ - test/test_resque_stuck_queue.rb
131
+ - test/test_set_custom_refresh_job.rb
132
+ - test/test_ver_2.rb