resqued 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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