qless-pool 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +3 -0
- data/LICENSE.txt +20 -0
- data/README.md +159 -0
- data/Rakefile +30 -0
- data/bin/qless-pool +7 -0
- data/features/basic_daemon_config.feature +68 -0
- data/features/step_definitions/daemon_steps.rb +33 -0
- data/features/step_definitions/qless-pool_steps.rb +156 -0
- data/features/support/aruba_daemon_support.rb +76 -0
- data/features/support/env.rb +1 -0
- data/lib/qless/pool.rb +415 -0
- data/lib/qless/pool/cli.rb +136 -0
- data/lib/qless/pool/logging.rb +65 -0
- data/lib/qless/pool/pool_factory.rb +43 -0
- data/lib/qless/pool/pooled_worker.rb +21 -0
- data/lib/qless/pool/tasks.rb +20 -0
- data/lib/qless/pool/version.rb +5 -0
- data/man/qless-pool.1 +88 -0
- data/man/qless-pool.1.ronn +92 -0
- data/man/qless-pool.yml.5 +46 -0
- data/man/qless-pool.yml.5.ronn +41 -0
- data/spec/mock_config.rb +6 -0
- data/spec/qless-pool-custom.yml.erb +1 -0
- data/spec/qless-pool.yml +13 -0
- data/spec/qless_pool_spec.rb +166 -0
- data/spec/spec_helper.rb +3 -0
- metadata +213 -0
data/Changelog.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2010 by Nicholas Evans <nick@ekenosen.net>, et al.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
20
|
+
|
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
Qless Pool
|
2
|
+
===========
|
3
|
+
|
4
|
+
[![Build Status](https://secure.travis-ci.org/wr0ngway/qless-pool.png)](http://travis-ci.org/wr0ngway/qless-pool)
|
5
|
+
|
6
|
+
Qless pool is a simple library for managing a pool of
|
7
|
+
[qless](http://github.com/seomoz/qless) workers. Given a a config file, it
|
8
|
+
manages your workers for you, starting up the appropriate number of workers for
|
9
|
+
each worker type. This is a fork of [resque-pool](https://github.com/nevans/resque-pool) with some commits from a [backupify fork of it](https://github.com/backupify/resque-pool/tree/maintain_count)
|
10
|
+
|
11
|
+
Benefits
|
12
|
+
---------
|
13
|
+
|
14
|
+
* Less config - With a simple YAML file, you can start up a pool daemon, and it
|
15
|
+
will monitor your workers for you. An example init.d script, monit config,
|
16
|
+
and chef cookbook are provided.
|
17
|
+
* Less memory - If you are using Ruby Enterprise Edition, or any ruby with
|
18
|
+
copy-on-write safe garbage collection, this should save you a *lot* of memory
|
19
|
+
when you are managing many workers.
|
20
|
+
* Faster startup - when you start many workers at once, they would normally
|
21
|
+
compete for CPU as they load their environments. Qless-pool can load the
|
22
|
+
environment once and fork all of the workers almost instantly.
|
23
|
+
|
24
|
+
Upgrading?
|
25
|
+
-----------
|
26
|
+
|
27
|
+
See
|
28
|
+
[Changelog.md](https://github.com/wr0ngway/qless-pool/blob/master/Changelog.md)
|
29
|
+
in case there are important or helpful changes.
|
30
|
+
|
31
|
+
How to use
|
32
|
+
-----------
|
33
|
+
|
34
|
+
### YAML file config
|
35
|
+
|
36
|
+
Create a `config/qless-pool.yml` (or `qless-pool.yml`) with your worker
|
37
|
+
counts. The YAML file supports both using root level defaults as well as
|
38
|
+
environment specific overrides (`RACK_ENV`, `RAILS_ENV`, and `QLESS_ENV`
|
39
|
+
environment variables can be used to determine environment). For example in
|
40
|
+
`config/qless-pool.yml`:
|
41
|
+
|
42
|
+
foo: 1
|
43
|
+
bar: 2
|
44
|
+
"foo,bar,baz": 1
|
45
|
+
|
46
|
+
production:
|
47
|
+
"foo,bar,baz": 4
|
48
|
+
|
49
|
+
### Rake task config
|
50
|
+
|
51
|
+
Require the rake tasks (`qless/pool/tasks`) in your `Rakefile`, load your
|
52
|
+
application environment, configure Qless as necessary, and configure
|
53
|
+
`qless:pool:setup` to disconnect all open files and sockets in the pool
|
54
|
+
manager and reconnect in the workers. For example, with rails you should put
|
55
|
+
the following into `lib/tasks/qless.rake`:
|
56
|
+
|
57
|
+
require 'qless/pool/tasks'
|
58
|
+
# this task will get called before qless:pool:setup
|
59
|
+
# and preload the rails environment in the pool manager
|
60
|
+
task "qless:setup" => :environment do
|
61
|
+
# generic worker setup, e.g. Hoptoad for failed jobs
|
62
|
+
end
|
63
|
+
task "qless:pool:setup" do
|
64
|
+
# close any sockets or files in pool manager
|
65
|
+
ActiveRecord::Base.connection.disconnect!
|
66
|
+
# and re-open them in the qless worker parent
|
67
|
+
Qless::Pool.after_prefork do |job|
|
68
|
+
ActiveRecord::Base.establish_connection
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
### Start the pool manager
|
73
|
+
|
74
|
+
Then you can start the queues via:
|
75
|
+
|
76
|
+
qless-pool --daemon --environment production
|
77
|
+
|
78
|
+
This will start up seven worker processes, one exclusively for the foo queue,
|
79
|
+
two exclusively for the bar queue, and four workers looking at all queues in
|
80
|
+
priority. With the config above, this is similar to if you ran the following:
|
81
|
+
|
82
|
+
rake qless:work RAILS_ENV=production QUEUES=foo &
|
83
|
+
rake qless:work RAILS_ENV=production QUEUES=bar &
|
84
|
+
rake qless:work RAILS_ENV=production QUEUES=bar &
|
85
|
+
rake qless:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
86
|
+
rake qless:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
87
|
+
rake qless:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
88
|
+
rake qless:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
89
|
+
|
90
|
+
The pool manager will stay around monitoring the qless worker parents, giving
|
91
|
+
three levels: a single pool manager, many worker parents, and one worker child
|
92
|
+
per worker (when the actual job is being processed). For example, `ps -ef f |
|
93
|
+
grep [r]esque` (in Linux) might return something like the following:
|
94
|
+
|
95
|
+
qless 13858 1 0 13:44 ? S 0:02 qless-pool-manager: managing [13867, 13875, 13871, 13872, 13868, 13870, 13876]
|
96
|
+
qless 13867 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Waiting for foo
|
97
|
+
qless 13868 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Waiting for bar
|
98
|
+
qless 13870 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Waiting for bar
|
99
|
+
qless 13871 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Waiting for foo,bar,baz
|
100
|
+
qless 13872 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Forked 7481 at 1280343254
|
101
|
+
qless 7481 13872 0 14:54 ? S 0:00 \_ qless-1.9.9: Processing foo since 1280343254
|
102
|
+
qless 13875 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Waiting for foo,bar,baz
|
103
|
+
qless 13876 13858 0 13:44 ? S 0:00 \_ qless-1.9.9: Forked 7485 at 1280343255
|
104
|
+
qless 7485 13876 0 14:54 ? S 0:00 \_ qless-1.9.9: Processing bar since 1280343254
|
105
|
+
|
106
|
+
Running as a daemon will default to placing the pidfile and logfiles in the
|
107
|
+
conventional rails locations, although you can configure that. See
|
108
|
+
`qless-pool --help` for more options.
|
109
|
+
|
110
|
+
SIGNALS
|
111
|
+
-------
|
112
|
+
|
113
|
+
The pool manager responds to the following signals:
|
114
|
+
|
115
|
+
* `HUP` - reload the config file, reload logfiles, restart all workers.
|
116
|
+
* `QUIT` - gracefully shut down workers (via `QUIT`) and shutdown the manager
|
117
|
+
after all workers are done.
|
118
|
+
* `INT` - gracefully shut down workers (via `QUIT`) and immediately shutdown manager
|
119
|
+
* `TERM` - immediately shut down workers (via `INT`) and immediately shutdown manager
|
120
|
+
_(configurable via command line options)_
|
121
|
+
* `WINCH` - _(only when running as a daemon)_ send `QUIT` to each worker, but
|
122
|
+
keep manager running (send `HUP` to reload config and restart workers)
|
123
|
+
* `USR1`/`USR2`/`CONT` - pass the signal on to all worker parents (see Qless docs).
|
124
|
+
|
125
|
+
Use `HUP` to help logrotate run smoothly and to change the number of workers
|
126
|
+
per worker type. Signals can be sent via the `kill` command, e.g.
|
127
|
+
`kill -HUP $master_pid`
|
128
|
+
|
129
|
+
Other Features
|
130
|
+
--------------
|
131
|
+
|
132
|
+
An example chef cookbook is provided (and should Just Work at Engine Yard as
|
133
|
+
is; just provide a `/data/#{app_name}/shared/config/qless-pool.yml` on your
|
134
|
+
utility instances). Even if you don't use chef you can use the example init.d
|
135
|
+
and monitrc erb templates in `examples/chef_cookbook/templates/default`.
|
136
|
+
|
137
|
+
You can also start a pool manager via `rake qless:pool` or from a plain old
|
138
|
+
ruby script by calling `Qless::Pool.run`.
|
139
|
+
|
140
|
+
Workers will watch the pool manager, and gracefully shutdown (after completing
|
141
|
+
their current job) if the manager process disappears before them.
|
142
|
+
|
143
|
+
You can specify an alternate config file by setting the `QLESS_POOL_CONFIG` or
|
144
|
+
with the `--config` command line option.
|
145
|
+
|
146
|
+
TODO
|
147
|
+
-----
|
148
|
+
|
149
|
+
See [the TODO list](https://github.com/wr0ngway/qless-pool/issues) at github issues.
|
150
|
+
|
151
|
+
Contributors
|
152
|
+
-------------
|
153
|
+
|
154
|
+
* Nicholas Evans (Author of resque-pool which this is a fork of)
|
155
|
+
* Jason Haruska (from resque-pool)
|
156
|
+
* John Schult (from resque-pool)
|
157
|
+
* Stephen Celis (from resque-pool)
|
158
|
+
* Vincent Agnello, Robert Kamunyori, Paul Kauders (from resque-pool)
|
159
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
# for loading the example config file in config/qless-pool.yml
|
5
|
+
require 'qless/pool/tasks'
|
6
|
+
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
9
|
+
t.rspec_opts = ["-c", "-f progress"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'cucumber/rake/task'
|
13
|
+
Cucumber::Rake::Task.new(:features) do |c|
|
14
|
+
c.profile = "rake"
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => [:spec, :features]
|
18
|
+
|
19
|
+
rule(/\.[1-9]$/ => [proc { |tn| "#{tn}.ronn" }]) do |t|
|
20
|
+
name = Qless::Pool.name.sub('::','-').upcase
|
21
|
+
version = "%s %s" % [name, Qless::Pool::VERSION.upcase]
|
22
|
+
|
23
|
+
manual = '--manual "%s"' % name
|
24
|
+
organization = '--organization "%s"' % version
|
25
|
+
sh "ronn #{manual} #{organization} <#{t.source} >#{t.name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
file 'man/qless-pool.1'
|
29
|
+
file 'man/qless-pool.yml.5'
|
30
|
+
task :manpages => ['man/qless-pool.1','man/qless-pool.yml.5']
|
data/bin/qless-pool
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
Feature: Basic qless-pool daemon configuration and operation
|
2
|
+
To easily manage a pool of qless workers, qless-pool provides a daemon with
|
3
|
+
simple configuration. Static configuration is handled in the
|
4
|
+
config/config.yml file and dynamic configuration is handled in the Rakefile.
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a file named "Rakefile" with:
|
8
|
+
"""
|
9
|
+
require 'qless/pool/tasks'
|
10
|
+
"""
|
11
|
+
|
12
|
+
Scenario: no config file
|
13
|
+
When I run the pool manager as "qless-pool"
|
14
|
+
Then the pool manager should report that it has started up
|
15
|
+
And the pool manager should report that the pool is empty
|
16
|
+
And the pool manager should have no child processes
|
17
|
+
When I send the pool manager the "QUIT" signal
|
18
|
+
Then the pool manager should finish
|
19
|
+
And the pool manager should report that it is finished
|
20
|
+
|
21
|
+
@slow_exit
|
22
|
+
Scenario: basic config file
|
23
|
+
Given a file named "config/qless-pool.yml" with:
|
24
|
+
"""
|
25
|
+
foo: 1
|
26
|
+
bar: 2
|
27
|
+
"bar,baz": 3
|
28
|
+
"""
|
29
|
+
When I run the pool manager as "qless-pool"
|
30
|
+
Then the pool manager should report that it has started up
|
31
|
+
And the pool manager should report that 6 workers are in the pool
|
32
|
+
And the pool manager should have 1 "foo" worker child processes
|
33
|
+
And the pool manager should have 2 "bar" worker child processes
|
34
|
+
And the pool manager should have 3 "bar, baz" worker child processes
|
35
|
+
When I send the pool manager the "QUIT" signal
|
36
|
+
Then the qless workers should all shutdown
|
37
|
+
And the pool manager should finish
|
38
|
+
And the pool manager should report that a "foo" worker has been reaped
|
39
|
+
And the pool manager should report that a "bar" worker has been reaped
|
40
|
+
And the pool manager should report that a "bar,baz" worker has been reaped
|
41
|
+
And the pool manager should report that it is finished
|
42
|
+
|
43
|
+
Scenario: daemonized
|
44
|
+
Given a directory named "log"
|
45
|
+
And a directory named "tmp/pids"
|
46
|
+
And a file named "config/qless-pool.yml" with:
|
47
|
+
"""
|
48
|
+
foo: 2
|
49
|
+
bar: 4
|
50
|
+
"baz,quux": 4
|
51
|
+
"""
|
52
|
+
When I run the pool manager as "qless-pool -d"
|
53
|
+
Then the pool manager should record its pid in "tmp/pids/qless-pool.pid"
|
54
|
+
And the pool manager should daemonize
|
55
|
+
And a file named "log/qless-pool.stdout.log" should exist
|
56
|
+
And a file named "log/qless-pool.stderr.log" should exist
|
57
|
+
And the pool manager should log that it has started up
|
58
|
+
And the pool manager should log that 10 workers are in the pool
|
59
|
+
And the pool manager should have 2 "foo" worker child processes
|
60
|
+
And the pool manager should have 4 "bar" worker child processes
|
61
|
+
And the pool manager should have 4 "baz, quux" worker child processes
|
62
|
+
When I send the pool manager the "QUIT" signal
|
63
|
+
Then the qless workers should all shutdown
|
64
|
+
And the pool manager daemon should finish
|
65
|
+
And the pool manager should log that a "foo" worker has been reaped
|
66
|
+
And the pool manager should log that a "bar" worker has been reaped
|
67
|
+
And the pool manager should log that a "baz,quux" worker has been reaped
|
68
|
+
And the pool manager should log that it is finished
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# syntactic sugar, and separate ivar. daemons aren't interactive
|
2
|
+
When /^I run "([^"]*)" in the background$/ do |cmd|
|
3
|
+
run_background(unescape(cmd))
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^the (output|logfiles) should contain the following lines \(with interpolated \$PID\):$/ do |output_logfiles, partial_output|
|
7
|
+
interpolate_background_pid(partial_output).split("\n").each do |line|
|
8
|
+
output_or_log(output_logfiles).should include(line)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
When /^I send "([^"]*)" the "([^"]*)" signal$/ do |cmd, signal|
|
13
|
+
send_signal(cmd, signal)
|
14
|
+
end
|
15
|
+
|
16
|
+
Then /^the "([^"]*)" process should finish$/ do |cmd|
|
17
|
+
# doesn't actually stop... just polls for exit
|
18
|
+
processes[cmd].stop
|
19
|
+
end
|
20
|
+
|
21
|
+
Before("@slow_exit") do
|
22
|
+
@aruba_timeout_seconds = 10
|
23
|
+
end
|
24
|
+
|
25
|
+
After do
|
26
|
+
kill_all_processes!
|
27
|
+
# now kill the daemon!
|
28
|
+
begin
|
29
|
+
Process.kill(9, @pid_from_pidfile) if @pid_from_pidfile
|
30
|
+
rescue Errno::ESRCH
|
31
|
+
end
|
32
|
+
#`pkill -9 qless-pool`
|
33
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
def process_should_exist(pid)
|
2
|
+
lambda { Process.kill(0, pid) }.should_not raise_error(Errno::ESRCH)
|
3
|
+
end
|
4
|
+
|
5
|
+
def process_should_not_exist(pid)
|
6
|
+
lambda { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
|
7
|
+
end
|
8
|
+
|
9
|
+
def grab_worker_pids(count, str)
|
10
|
+
puts "TODO: check output_or_log for #{count} worker started messages"
|
11
|
+
pid_regex = (1..count).map { '(\d+)' }.join ', '
|
12
|
+
full_regex = /qless-pool-manager\[aruba\]\[\d+\]: Pool contains worker PIDs: \[#{pid_regex}\]/m
|
13
|
+
str.should =~ full_regex
|
14
|
+
@worker_pids = full_regex.match(str).captures.map {|pid| pid.to_i }
|
15
|
+
end
|
16
|
+
|
17
|
+
def output_or_logfiles_string(report_log)
|
18
|
+
case report_log
|
19
|
+
when "report", "output"
|
20
|
+
"output"
|
21
|
+
when "log", "logfiles"
|
22
|
+
"logfiles"
|
23
|
+
else
|
24
|
+
raise ArgumentError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def output_or_log(report_log)
|
29
|
+
case report_log
|
30
|
+
when "report", "output"
|
31
|
+
interactive_output
|
32
|
+
when "log", "logfiles"
|
33
|
+
in_current_dir do
|
34
|
+
File.read("log/qless-pool.stdout.log") << File.read("log/qless-pool.stderr.log")
|
35
|
+
end
|
36
|
+
else
|
37
|
+
raise ArgumentError
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class NotFinishedStarting < StandardError; end
|
42
|
+
def worker_processes_for(queues)
|
43
|
+
children_of(background_pid).select do |pid, cmd|
|
44
|
+
raise NotFinishedStarting if cmd =~ /Starting$/
|
45
|
+
cmd =~ /^Qless-\d+.\d+.\d+: Waiting for #{queues} \(ordered\) at/
|
46
|
+
end
|
47
|
+
rescue NotFinishedStarting
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
|
51
|
+
def children_of(ppid)
|
52
|
+
osx = RUBY_PLATFORM =~ /darwin/i
|
53
|
+
ps = `ps -eo ppid,pid,#{osx ? 'args' : 'cmd'} | grep '^ *#{ppid} '`
|
54
|
+
ps.split(/\s*\n/).map do |line|
|
55
|
+
_, pid, cmd = line.strip.split(/\s+/, 3)
|
56
|
+
[pid, cmd]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
When /^I run the pool manager as "([^"]*)"$/ do |cmd|
|
61
|
+
@pool_manager_process = run_background(unescape(cmd))
|
62
|
+
end
|
63
|
+
|
64
|
+
When /^I send the pool manager the "([^"]*)" signal$/ do |signal|
|
65
|
+
Process.kill signal, background_pid
|
66
|
+
output_logfiles = @pid_from_pidfile ? "logfiles" : "output"
|
67
|
+
case signal
|
68
|
+
when "QUIT"
|
69
|
+
keep_trying do
|
70
|
+
step "the #{output_logfiles} should contain the following lines (with interpolated $PID):", <<-EOF
|
71
|
+
qless-pool-manager[aruba][$PID]: QUIT: graceful shutdown, waiting for children
|
72
|
+
EOF
|
73
|
+
end
|
74
|
+
else
|
75
|
+
raise ArgumentError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Then /^the pool manager should record its pid in "([^"]*)"$/ do |pidfile|
|
80
|
+
in_current_dir do
|
81
|
+
keep_trying do
|
82
|
+
File.should be_file(pidfile)
|
83
|
+
@pid_from_pidfile = File.read(pidfile).to_i
|
84
|
+
@pid_from_pidfile.should_not == 0
|
85
|
+
process_should_exist(@pid_from_pidfile)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Then /^the pool manager should daemonize$/ do
|
91
|
+
stop_processes!
|
92
|
+
end
|
93
|
+
|
94
|
+
Then /^the pool manager daemon should finish$/ do
|
95
|
+
keep_trying do
|
96
|
+
process_should_not_exist(@pid_from_pidfile)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# nomenclature: "report" => output to stdout/stderr
|
101
|
+
# "log" => output to default logfile
|
102
|
+
|
103
|
+
Then /^the pool manager should (report|log) that it has started up$/ do |report_log|
|
104
|
+
keep_trying do
|
105
|
+
step "the #{output_or_logfiles_string(report_log)} should contain the following lines (with interpolated $PID):", <<-EOF
|
106
|
+
qless-pool-manager[aruba][$PID]: Qless Pool running in test environment
|
107
|
+
qless-pool-manager[aruba][$PID]: started manager
|
108
|
+
EOF
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
Then /^the pool manager should (report|log) that the pool is empty$/ do |report_log|
|
113
|
+
step "the #{output_or_logfiles_string(report_log)} should contain the following lines (with interpolated $PID):", <<-EOF
|
114
|
+
qless-pool-manager[aruba][$PID]: Pool is empty
|
115
|
+
EOF
|
116
|
+
end
|
117
|
+
|
118
|
+
Then /^the pool manager should (report|log) that (\d+) workers are in the pool$/ do |report_log, count|
|
119
|
+
grab_worker_pids Integer(count), output_or_log(report_log)
|
120
|
+
end
|
121
|
+
|
122
|
+
Then /^the qless workers should all shutdown$/ do
|
123
|
+
@worker_pids.each do |pid|
|
124
|
+
keep_trying do
|
125
|
+
process_should_not_exist(pid)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
Then "the pool manager should have no child processes" do
|
131
|
+
children_of(background_pid).should have(:no).keys
|
132
|
+
end
|
133
|
+
|
134
|
+
Then /^the pool manager should have (\d+) "([^"]*)" worker child processes$/ do |count, queues|
|
135
|
+
worker_processes_for(queues).should have(Integer(count)).members
|
136
|
+
end
|
137
|
+
|
138
|
+
Then "the pool manager should finish" do
|
139
|
+
# assuming there will not be multiple processes running
|
140
|
+
stop_processes!
|
141
|
+
end
|
142
|
+
|
143
|
+
Then /^the pool manager should (report|log) that it is finished$/ do |report_log|
|
144
|
+
step "the #{output_or_logfiles_string(report_log)} should contain the following lines (with interpolated $PID):", <<-EOF
|
145
|
+
qless-pool-manager[aruba][$PID]: manager finished
|
146
|
+
EOF
|
147
|
+
end
|
148
|
+
|
149
|
+
Then /^the pool manager should (report|log) that a "([^"]*)" worker has been reaped$/ do |report_log, worker_type|
|
150
|
+
step 'the '+ output_or_logfiles_string(report_log) +' should match /Reaped qless worker\[\d+\] \(status: 0\) queues: '+ worker_type + '/'
|
151
|
+
end
|
152
|
+
|
153
|
+
Then /^the logfiles should match \/([^\/]*)\/$/ do |partial_output|
|
154
|
+
output_or_log("log").should =~ /#{partial_output}/
|
155
|
+
end
|
156
|
+
|