qless-pool 0.1.0
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.
- 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
|
+
[](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
|
+
|