resque_stuck_queue 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YWNkZWJjMzVlMTZlNmI4ZDNiZjk5MTk2ZjFiOTVhZTIxYjA4ZDY1Ng==
4
+ Y2RiMWFkM2ZmMGJmOWI1YzcwYzg5MWUyNjU3MTEzNWQwYmZiOWQ1YQ==
5
5
  data.tar.gz: !binary |-
6
- NDlmNDlmZGI3OThiMDk2NjJiZGZhZDlmY2YxNzZhOGY0ZmU1YzMxNQ==
6
+ NjQ2ODNlOTNmMDMzZWU1MDU2NWE1NTc4YmQ1NzAwOGFlYzNlOTU5Nw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ODgyNjJhMjNiYjNhNWRjNjBhYzhiNGUxODNmZDhiNWJiNDViODQ1ZTBlNTdk
10
- MzU2ZjU3M2MyMWY0OGE5ZWIzYTBlMGI4OTEzZGFkY2RlNjkyNWU2MmI0NjYy
11
- NDQ3M2IyY2E3YTAwYzUyODExZDNkY2E2ZmI3ZDVjYzAwYWVlN2Q=
9
+ Mzc4ZTI4NjM2ZjlhY2ExNDM3NDhmMjU1NTA0ODE2Y2I3MzkwYzMxNDE3NTNk
10
+ YThjNjQ2ZDhkZjY5Nzk2YzAwMWZhZjgxOWNjMThiYzFhNGJlZWVjZjMzY2Rj
11
+ ZTZjZThlOGQyMzMwMzFlZmE1NTFmNDE4NzY4NmQ3ZTU1MDAwNDI=
12
12
  data.tar.gz: !binary |-
13
- NzM4ZjQyMDQzOTI2MDQyNTExMzQyNzEwNTAxM2M0NmRiYzM2YWJmMmQyYmFk
14
- MTMxZWM1YmY3Nzc2ODM0N2M3MTM3NjI2ZmYxNDFjNDc5ZmUyNmVmZmIxMGQ5
15
- MjkyNWNhOWZkNTNmNWVmM2ExNjg5ZGNkOGRmOTk0ZGU5NGQwYjA=
13
+ YzIzYWMxYWVkZGRiYjdhY2Y3ZDNlYzQ1NzcyYzQ2ZTcxZjM1NTE5NDgyMDU1
14
+ OTFkMmZjNWM5NjJiZmNkM2MyNDIyMWY5Y2Q4NTk4MDZkMTViMDY2ZDlhNDgz
15
+ NjQ0NGJiNzEwNDIyN2Y4NTJjZTYwODI0ZTRiYjgwYWM5OGI1MGU=
data/README.md CHANGED
@@ -16,8 +16,6 @@ It will trigger a pre-defined proc (see below) if the last time the hearbeat job
16
16
 
17
17
  ## Usage
18
18
 
19
- Add this to wherever you're setting up resque (config/initializers or wherever).
20
-
21
19
  Configure it first:
22
20
 
23
21
  <pre>
@@ -41,6 +39,10 @@ Resque::StuckQueue.config[:global_key] = "name-the-refresh-key-as-you-please"
41
39
 
42
40
  # optional, if you want the resque-stuck-queue threads to explicitly raise, default is false
43
41
  Resque::StuckQueue.config[:abort_on_exception] = true
42
+
43
+ # optional, pass a logger. Default a ruby logger will be instantiated. Needs to respond to that interface.
44
+ Resque::StuckQueue.config[:logger] = Logger.new($stdout)
45
+
44
46
  </pre>
45
47
 
46
48
  Then start it:
@@ -57,6 +59,16 @@ Resque::StuckQueue.stop # this will block until the threads end
57
59
  Resque::StuckQueue.force_stop! # force kill those threads and let's move on
58
60
  </pre>
59
61
 
62
+ ## Deployment/Integration
63
+
64
+ * Include this in the app in a config initializer of some sort.
65
+
66
+ Note though, the resque-stuck threads will live alongside the app server process so you will need to explicitely handle `start` _and_ `stop`. If you're deployed in a forking-server environment and the whatever process has this does not get restarted the threads will keep on going indefinitely.
67
+
68
+ * Run this as a daemon somewhere alongside the app/in your setup.
69
+
70
+ <!-- TODO example -->
71
+
60
72
  ## Tests
61
73
 
62
74
  Run the tests:
data/THOUGHTS CHANGED
@@ -28,4 +28,5 @@ verify @config options, raise if no handler, etc.
28
28
  - ensure it only runs from the server box and not the resque box??
29
29
  (the deploy restarts the server but not resque workers)
30
30
 
31
-
31
+ add a 'resque_stuck_queue/tasks' bit? See tres eg
32
+ require 'resque/stuck_queue' instead?
@@ -7,13 +7,15 @@ Redis::Classy.db = Resque.redis
7
7
  # TODO move this require into a configurable?
8
8
  require 'resque'
9
9
 
10
+ require 'logger'
11
+
10
12
  module Resque
11
13
  module StuckQueue
12
14
 
13
15
  GLOBAL_KEY = "resque-stuck-queue"
14
16
  HEARTBEAT = 60 * 60 # check/refresh every hour
15
17
  TRIGGER_TIMEOUT = 5 * 60 * 60 # warn/trigger 5 hours
16
- HANDLER = proc { $stderr.puts("Shit gone bad with them queues.") }
18
+ HANDLER = proc { $stdout.puts("Shit gone bad with them queues.") }
17
19
 
18
20
  class << self
19
21
 
@@ -38,6 +40,10 @@ module Resque
38
40
  @config ||= {}
39
41
  end
40
42
 
43
+ def logger
44
+ @logger ||= (config[:logger] || Logger.new($stdout))
45
+ end
46
+
41
47
  def start_in_background
42
48
  Thread.new do
43
49
  self.start
@@ -65,34 +71,44 @@ module Resque
65
71
  # fo-eva.
66
72
  @threads.map(&:join)
67
73
 
74
+ logger.info("threads stopped")
68
75
  @stopped = true
69
76
  end
70
77
 
71
- # for tests
72
78
  def stop
73
- @config = config.dup #unfreeze
74
- @running = false
75
-
79
+ reset!
76
80
  # wait for clean thread shutdown
77
81
  while @stopped == false
78
82
  sleep 1
79
83
  end
84
+ logger.info("Stopped")
80
85
  end
81
86
 
82
87
  def force_stop!
83
88
  @threads.map(&:kill)
89
+ reset!
90
+ logger.info("Force stopped")
91
+ end
92
+
93
+ def reset!
94
+ # clean state so we can stop and start in the same process.
95
+ @config = config.dup #unfreeze
96
+ @logger = nil
97
+ @running = false
84
98
  end
85
99
 
86
100
  private
87
101
 
88
102
  def enqueue_repeating_refresh_job
89
103
  @threads << Thread.new do
104
+ logger.info("Starting heartbeat thread")
90
105
  while @running
91
106
  wait_for_it
92
107
  # we want to go through resque jobs, because that's what we're trying to test here:
93
108
  # ensure that jobs get executed and the time is updated!
94
109
  #
95
110
  # TODO REDIS 2.0 compat
111
+ logger.info("Sending refresh job")
96
112
  Resque.enqueue(RefreshLatestTimestamp, global_key)
97
113
  end
98
114
  end
@@ -100,12 +116,14 @@ module Resque
100
116
 
101
117
  def setup_checker_thread
102
118
  @threads << Thread.new do
119
+ logger.info("Starting checker thread")
103
120
  while @running
104
121
  wait_for_it
105
122
  mutex = Redis::Mutex.new('resque_stuck_queue_lock', block: 0)
106
123
  if mutex.lock
107
124
  begin
108
125
  if Time.now.to_i - last_time_worked > max_wait_time
126
+ logger.info("Triggering handler at #{Time.now} (pid: #{Process.pid})")
109
127
  trigger_handler
110
128
  end
111
129
  ensure
@@ -1,5 +1,5 @@
1
1
  module Resque
2
2
  module StuckQueue
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -0,0 +1,30 @@
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 setup
8
+ Resque::StuckQueue.config[:trigger_timeout] = 1
9
+ Resque::StuckQueue.config[:heartbeat] = 1
10
+ Resque::StuckQueue.config[:abort_on_exception] = true
11
+ end
12
+
13
+ def teardown
14
+ Resque::StuckQueue.reset!
15
+ end
16
+
17
+ def test_has_logger
18
+ puts "#{__method__}"
19
+ begin
20
+ Resque::StuckQueue.config[:logger] = Logger.new($stdout)
21
+ start_and_stop_loops_after(2)
22
+ assert true, "should not have raised"
23
+ rescue
24
+ assert false, "should have succeeded with good logger"
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque_stuck_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shai Rosenfeld
@@ -74,6 +74,7 @@ files:
74
74
  - test/test_collision.rb
75
75
  - test/test_helper.rb
76
76
  - test/test_integration.rb
77
+ - test/test_logger.rb
77
78
  - test/test_resque_stuck_queue.rb
78
79
  homepage: https://github.com/shaiguitar/resque_stuck_queue/
79
80
  licenses:
@@ -105,5 +106,6 @@ test_files:
105
106
  - test/test_collision.rb
106
107
  - test/test_helper.rb
107
108
  - test/test_integration.rb
109
+ - test/test_logger.rb
108
110
  - test/test_resque_stuck_queue.rb
109
111
  has_rdoc: