resqued 0.7.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d66bf0dfa9299a44f871ae9835183600f6cc4e79
4
- data.tar.gz: 318a6d0ec20aebbaf97260c3f2253394187ae2e1
3
+ metadata.gz: dab65ebe5befd4cb605dc27208740e8c11079ca6
4
+ data.tar.gz: 73d6a230a3273aaf351e55008a01fe4a0a479944
5
5
  SHA512:
6
- metadata.gz: cd97e21578a9cddaf82210459dc148790ed65ba92cd92c0d013764b03826df4683414ec1bfe56eeb73ebfe1bfe0854ba49826885a94c0c1ea38461e82a4affce
7
- data.tar.gz: d8b4de064f53197605f7fc64bec9954a0bc8f4003bcd0c7334581043941e6e4762d42db0ee823a6c7ac085eaf6eb990be6d660b4dfd733bf877be09aa698ef5d
6
+ metadata.gz: f8215347e188cbd78fef8561cfaed3ae9e00156de9bb255dd3a2fc90d3b2dbe3dc30870ad44e22a95e73b57f798be7cd169133b07779c93c5a180394b0be242e
7
+ data.tar.gz: 249de2ac4fb9a5d40c97322b9d8176907bee59748051f22679cd1bba8eff6154256cd4b3b6d330097e3aaf790798185eae503240dc0589a5f5288f20007a95f2
data/exe/resqued CHANGED
@@ -46,6 +46,7 @@ end
46
46
 
47
47
  opts.parse!
48
48
  options[:config_paths] = ARGV
49
+ options[:status_pipe] = STDOUT
49
50
 
50
51
  if options[:config_paths].size == 0
51
52
  puts opts
@@ -73,6 +73,7 @@ module Resqued
73
73
  case line = @master_socket.readline
74
74
  when /^\+(\d+),(.*)$/
75
75
  worker_pids[$1] = $2
76
+ on_activity.worker_started($1) if on_activity
76
77
  when /^-(\d+)$/
77
78
  worker_pids.delete($1)
78
79
  on_activity.worker_finished($1) if on_activity
@@ -19,6 +19,7 @@ module Resqued
19
19
  def initialize(options)
20
20
  @config_paths = options.fetch(:config_paths)
21
21
  @pidfile = options.fetch(:master_pidfile) { nil }
22
+ @status_pipe = options.fetch(:status_pipe) { nil }
22
23
  @listener_backoff = Backoff.new
23
24
  @listeners_created = 0
24
25
  end
@@ -112,6 +113,7 @@ module Resqued
112
113
  return if @current_listener || @listener_backoff.wait?
113
114
  @current_listener = ListenerProxy.new(:config_paths => @config_paths, :running_workers => all_listeners.map { |l| l.running_workers }.flatten, :listener_id => next_listener_id)
114
115
  @current_listener.run
116
+ listener_status @current_listener, 'start'
115
117
  @listener_backoff.started
116
118
  listener_pids[@current_listener.pid] = @current_listener
117
119
  write_procline
@@ -127,10 +129,16 @@ module Resqued
127
129
  end
128
130
  end
129
131
 
132
+ # Listener message: A worker just started working.
133
+ def worker_started(pid)
134
+ worker_status(pid, 'start')
135
+ end
136
+
130
137
  # Listener message: A worker just stopped working.
131
138
  #
132
139
  # Forwards the message to the other listeners.
133
140
  def worker_finished(pid)
141
+ worker_status(pid, 'stop')
134
142
  all_listeners.each do |other|
135
143
  other.worker_finished(pid)
136
144
  end
@@ -140,6 +148,7 @@ module Resqued
140
148
  #
141
149
  # Promotes a booting listener to be the current listener.
142
150
  def listener_running(listener)
151
+ listener_status(listener, 'ready')
143
152
  if listener == @current_listener
144
153
  kill_listener(:QUIT, @last_good_listener)
145
154
  @last_good_listener = nil
@@ -189,7 +198,9 @@ module Resqued
189
198
  @listener_backoff.died
190
199
  @current_listener = nil
191
200
  end
192
- listener_pids.delete(lpid).dispose # This may leak workers.
201
+ dead_listener = listener_pids.delete(lpid)
202
+ listener_status dead_listener, 'stop'
203
+ dead_listener.dispose
193
204
  write_procline
194
205
  else
195
206
  return
@@ -234,5 +245,21 @@ module Resqued
234
245
  def write_procline
235
246
  $0 = "#{procline_version} master [gen #{@listeners_created}] [#{listener_pids.size} running] #{ARGV.join(' ')}"
236
247
  end
248
+
249
+ def listener_status(listener, status)
250
+ if listener && listener.pid
251
+ status_message('listener', listener.pid, status)
252
+ end
253
+ end
254
+
255
+ def worker_status(pid, status)
256
+ status_message('worker', pid, status)
257
+ end
258
+
259
+ def status_message(type, pid, status)
260
+ if @status_pipe
261
+ @status_pipe.write("#{type},#{pid},#{status}\n")
262
+ end
263
+ end
237
264
  end
238
265
  end
@@ -0,0 +1,84 @@
1
+ # This file includes example assertions for your resqued configuration.
2
+ #
3
+ # assert_resqued 'config/resqued/environment.rb', 'config/resqued/pool-a.rb'
4
+ module Resqued
5
+ module TestCase
6
+ module ForkToStart
7
+ # Public: Fork a process that spins up a Resqued::Master process directly.
8
+ def assert_resqued(*configs)
9
+ options = configs.last.is_a?(Hash) ? configs.pop : {}
10
+ check_workers = options.fetch(:expect_workers, false)
11
+ worker_timeout = options.fetch(:worker_timeout, 5)
12
+ resqued_bin = options.fetch(:resqued_bin) { `which resqued || bundle exec which resqued`.chomp }
13
+ status = IO.pipe
14
+ if pid = fork
15
+ message = read_status_from_resqued(:pipe => status[0], :pid => pid)
16
+ if message !~ /^listener,\d+,start$/
17
+ fail "Expected listener to start, but received #{message.inspect}"
18
+ end
19
+ message = read_status_from_resqued(:pipe => status[0], :pid => pid)
20
+ if message !~ /^listener,\d+,ready$/
21
+ fail "Expected listener to be ready, but received #{message.inspect}"
22
+ end
23
+ if check_workers
24
+ start = Time.now
25
+ workers_started = 0
26
+ loop do
27
+ elapsed = Time.now - start
28
+ time_remaining = worker_timeout - elapsed
29
+ break unless time_remaining > 0
30
+ if message = read_status_from_resqued(:pipe => status[0], :pid => pid, :timeout => time_remaining)
31
+ if message =~ /worker,\d+,start/
32
+ workers_started = workers_started + 1
33
+ else
34
+ fail "Expected to see workers starting, instead saw #{message.inspect}"
35
+ end
36
+ end
37
+ end
38
+ if workers_started == 0
39
+ fail "Expected at least one worker to start, but none did"
40
+ end
41
+ end
42
+ else
43
+ $0 = "resqued master for #{$0}"
44
+ unless ENV['NOISY_RESQUED_TESTS']
45
+ devnull = File.open('/dev/null', 'w')
46
+ $stdout.reopen(devnull)
47
+ $stderr.reopen(devnull)
48
+ end
49
+ begin
50
+ # This should match how `exe/resqued` starts the master process.
51
+ require 'resqued'
52
+ Resqued::START_CTX['$0'] = resqued_bin
53
+ Resqued::Master.new(:config_paths => configs, :status_pipe => status[1]).run
54
+ rescue Object => e
55
+ # oops
56
+ end
57
+ exit! # Do not make this look like a failing test.
58
+ end
59
+ ensure
60
+ begin
61
+ Process.kill :QUIT, pid
62
+ Process.waitpid2(pid) if pid
63
+ rescue Errno::ESRCH, Errno::ECHILD
64
+ # already dead.
65
+ end
66
+ end
67
+
68
+ def read_status_from_resqued(options)
69
+ status = options.fetch(:pipe)
70
+ pid = options.fetch(:pid)
71
+ timeout = options[:timeout]
72
+ loop do
73
+ if IO.select([status], nil, nil, timeout || 2)
74
+ return status.readline.chomp
75
+ elsif dead = Process.waitpid2(pid, Process::WNOHANG)
76
+ fail "Resqued stopped too soon."
77
+ elsif timeout
78
+ return nil
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,3 +1,3 @@
1
1
  module Resqued
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resqued
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Burke
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2013-10-22 00:00:00.000000000 Z
11
+ date: 2013-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kgio
@@ -145,6 +145,7 @@ files:
145
145
  - lib/resqued/pidfile.rb
146
146
  - lib/resqued/procline_version.rb
147
147
  - lib/resqued/sleepy.rb
148
+ - lib/resqued/test_case.rb
148
149
  - lib/resqued/version.rb
149
150
  - lib/resqued/worker.rb
150
151
  - lib/resqued.rb