resque-pool 0.0.12.1.alpha → 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
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## 0.1.0 (unreleased)
|
|
2
|
+
|
|
3
|
+
* new feature: `resque-pool` command line interface
|
|
4
|
+
* this replaces need for a special startup script.
|
|
5
|
+
* manages PID file, logfiles, daemonizing, etc.
|
|
6
|
+
* `resque-pool --help` for more info and options
|
|
7
|
+
* updated example config, init.d script, including a chef recipe that should
|
|
8
|
+
work at EngineYard.
|
|
9
|
+
|
|
10
|
+
## 0.0.10 (2010-08-31)
|
|
11
|
+
|
|
12
|
+
* remove rubygems 1.3.6 dependency
|
|
13
|
+
|
|
14
|
+
## 0.0.9 (2010-08-26)
|
|
15
|
+
|
|
16
|
+
* new feature: `RESQUE_POOL_CONFIG` environment variable to set alt config file
|
|
17
|
+
* upgraded to resque 1.10, removing `Resque::Worker` monkeypatch
|
|
18
|
+
|
|
19
|
+
## 0.0.8 (2010-08-20)
|
|
20
|
+
|
|
21
|
+
* bugfix: using (or not using) environments in config file
|
|
22
|
+
|
|
23
|
+
## 0.0.7 (2010-08-16)
|
|
24
|
+
|
|
25
|
+
* new feature: split by environments in config file
|
|
26
|
+
* added example startup script, Rakefile, and monit config
|
|
27
|
+
|
|
28
|
+
## 0.0.5 (2010-06-29)
|
|
29
|
+
|
|
30
|
+
* bugfix: worker processes not shutting down after orphaned
|
|
31
|
+
|
|
32
|
+
## 0.0.4 (2010-06-29)
|
|
33
|
+
|
|
34
|
+
* first release used in production
|
data/README.md
CHANGED
|
@@ -2,33 +2,31 @@ Resque Pool
|
|
|
2
2
|
===========
|
|
3
3
|
|
|
4
4
|
Resque pool is a simple library for managing a pool of resque workers. Given a
|
|
5
|
-
a config file
|
|
6
|
-
|
|
5
|
+
a config file, it manages your workers for you, starting up the appropriate
|
|
6
|
+
number of workers for each.
|
|
7
7
|
|
|
8
8
|
Benefits
|
|
9
9
|
---------
|
|
10
10
|
|
|
11
|
-
* Less
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
you.
|
|
17
|
-
* Faster startup -
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
* Less config - With a simple YAML file, you can start up a pool daemon, and it
|
|
12
|
+
will monitor your workers for you. An example init.d script, monit config,
|
|
13
|
+
and chef cookbook are provided.
|
|
14
|
+
* Less memory - If you are using Ruby Enterprise Edition, or any ruby with
|
|
15
|
+
copy-on-write safe garbage collection, this should save you a lot of memory
|
|
16
|
+
when you are managing many workers.
|
|
17
|
+
* Faster startup - when you start many workers at once, they would normally
|
|
18
|
+
compete for CPU as they load their environments. Resque-pool can load the
|
|
19
|
+
environment once and almost instantaneously fork all of the workers.
|
|
20
20
|
|
|
21
21
|
How to use
|
|
22
22
|
-----------
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
counts. To use resque-pool, require its rake tasks (`resque/pool/tasks`) in
|
|
26
|
-
your rake file, and run `resque-pool`
|
|
24
|
+
### YAML file config
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
Create a `config/resque-pool.yml` with your worker counts. The YAML file
|
|
27
|
+
supports both using root level defaults as well as environment specific
|
|
28
|
+
overrides (`RACK_ENV`, `RAILS_ENV`, and `RESQUE_ENV` environment variables can
|
|
29
|
+
be used to determine environment). For example in `config/resque-pool.yml`:
|
|
32
30
|
|
|
33
31
|
foo: 1
|
|
34
32
|
bar: 2
|
|
@@ -37,16 +35,21 @@ resque-pool with rails, in `config/resque-pool.yml`:
|
|
|
37
35
|
production:
|
|
38
36
|
"foo,bar,baz": 4
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
### Rake task config
|
|
39
|
+
|
|
40
|
+
Require the rake tasks (`resque/pool/tasks`) in your rake file, configure
|
|
41
|
+
Resque as necessary, and configure `Resque::Pool` to disconnect all open
|
|
42
|
+
sockets in the pool manager and reconnect in the workers. For example, with
|
|
43
|
+
rails you should put the following into `lib/tasks/resque.rake`:
|
|
41
44
|
|
|
42
45
|
require 'resque/pool/tasks'
|
|
43
46
|
# this task will get called before resque:pool:setup
|
|
44
|
-
# preload the rails environment in the pool
|
|
47
|
+
# and preload the rails environment in the pool manager
|
|
45
48
|
task "resque:setup" => :environment do
|
|
46
49
|
# generic worker setup, e.g. Hoptoad for failed jobs
|
|
47
50
|
end
|
|
48
51
|
task "resque:pool:setup" do
|
|
49
|
-
# close any sockets or files in pool
|
|
52
|
+
# close any sockets or files in pool manager
|
|
50
53
|
ActiveRecord::Base.connection.disconnect!
|
|
51
54
|
# and re-open them in the resque worker parent
|
|
52
55
|
Resque::Pool.after_prefork do |job|
|
|
@@ -54,29 +57,30 @@ and in `lib/tasks/resque.rake`:
|
|
|
54
57
|
end
|
|
55
58
|
end
|
|
56
59
|
|
|
60
|
+
### Start the pool manager
|
|
61
|
+
|
|
57
62
|
Then you can start the queues via:
|
|
58
63
|
|
|
59
64
|
resque-pool --environment production
|
|
60
65
|
|
|
61
66
|
This will start up seven worker processes, one exclusively for the foo queue,
|
|
62
67
|
two exclusively for the bar queue, and four workers looking at all queues in
|
|
63
|
-
priority.
|
|
64
|
-
|
|
65
|
-
rake resque:work RAILS_ENV=production
|
|
66
|
-
rake resque:work RAILS_ENV=production
|
|
67
|
-
rake resque:work RAILS_ENV=production
|
|
68
|
-
rake resque:work RAILS_ENV=production
|
|
69
|
-
rake resque:work RAILS_ENV=production
|
|
70
|
-
rake resque:work RAILS_ENV=production
|
|
71
|
-
rake resque:work RAILS_ENV=production
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
rails 13858 1 0 13:44 ? S 0:02 resque-pool-master: managing [13867, 13875, 13871, 13872, 13868, 13870, 13876]
|
|
68
|
+
priority. With the config above, this is similar to if you ran the following:
|
|
69
|
+
|
|
70
|
+
rake resque:work RAILS_ENV=production QUEUES=foo &
|
|
71
|
+
rake resque:work RAILS_ENV=production QUEUES=bar &
|
|
72
|
+
rake resque:work RAILS_ENV=production QUEUES=bar &
|
|
73
|
+
rake resque:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
|
74
|
+
rake resque:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
|
75
|
+
rake resque:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
|
76
|
+
rake resque:work RAILS_ENV=production QUEUES=foo,bar,baz &
|
|
77
|
+
|
|
78
|
+
The pool manager will stay around monitoring the resque worker parents, giving
|
|
79
|
+
three levels: a single pool manager, many worker parents, and one worker child
|
|
80
|
+
per worker (when the actual job is being processed). For example, `ps -ef f |
|
|
81
|
+
grep [r]esque` (in Linux) might return something like the following:
|
|
82
|
+
|
|
83
|
+
rails 13858 1 0 13:44 ? S 0:02 resque-pool-manager: managing [13867, 13875, 13871, 13872, 13868, 13870, 13876]
|
|
80
84
|
rails 13867 13858 0 13:44 ? S 0:00 \_ resque-1.9.9: Waiting for foo
|
|
81
85
|
rails 13868 13858 0 13:44 ? S 0:00 \_ resque-1.9.9: Waiting for bar
|
|
82
86
|
rails 13870 13858 0 13:44 ? S 0:00 \_ resque-1.9.9: Waiting for bar
|
|
@@ -87,16 +91,21 @@ return something like the following:
|
|
|
87
91
|
rails 13876 13858 0 13:44 ? S 0:00 \_ resque-1.9.9: Forked 7485 at 1280343255
|
|
88
92
|
rails 7485 13876 0 14:54 ? S 0:00 \_ resque-1.9.9: Processing bar since 1280343254
|
|
89
93
|
|
|
94
|
+
You can also run resque-pool as a daemon via `--daemon`. It will default to
|
|
95
|
+
placing the pidfile and logfiles in the rails default locations, which you may
|
|
96
|
+
want to configure. The `RAILS_ENV` can be specified via `--environment`. See
|
|
97
|
+
`resque-pool --help` for more options.
|
|
98
|
+
|
|
90
99
|
SIGNALS
|
|
91
100
|
-------
|
|
92
101
|
|
|
93
|
-
The pool
|
|
102
|
+
The pool manager responds to the following signals:
|
|
94
103
|
|
|
95
104
|
* `HUP` - reload the config file, e.g. to change the number of workers per queue list
|
|
96
|
-
* `QUIT` - send `QUIT` to each worker parent and shutdown the
|
|
97
|
-
* `INT` - send `QUIT` to each worker parent and immediately shutdown
|
|
98
|
-
* `TERM` - send `TERM` to each worker parent and immediately shutdown
|
|
99
|
-
* `WINCH` - send `QUIT` to each worker, but keep
|
|
105
|
+
* `QUIT` - send `QUIT` to each worker parent and shutdown the manager after all workers are done.
|
|
106
|
+
* `INT` - send `QUIT` to each worker parent and immediately shutdown manager
|
|
107
|
+
* `TERM` - send `TERM` to each worker parent and immediately shutdown manager
|
|
108
|
+
* `WINCH` - send `QUIT` to each worker, but keep manager running (send `HUP` to reload config and restart workers)
|
|
100
109
|
* `USR1`/`USR2`/`CONT` - send the signal on to all worker parents (see Resque docs).
|
|
101
110
|
|
|
102
111
|
After a `HUP`, workers that are no longer needed will be gracefully shutdown
|
|
@@ -105,46 +114,43 @@ via `QUIT`.
|
|
|
105
114
|
Other Features
|
|
106
115
|
--------------
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
`examples/chef_cookbook/templates/default`, as erb templates. Just copy them
|
|
114
|
-
into place, filling in the erb variables as necessary. An example chef recipe
|
|
115
|
-
is also provided (it should work at Engine Yard as is; just provide a
|
|
116
|
-
`/data/#{app_name}/shared/config/resque-pool.yml` on your utility servers).
|
|
117
|
-
|
|
118
|
-
You can also run `resque-pool` via the `resque:pool` rake task or from a plain
|
|
119
|
-
old ruby script by calling `Resque::Pool.run`.
|
|
117
|
+
An example chef recipe is provided (it should work at Engine Yard as is; just
|
|
118
|
+
provide a `/data/#{app_name}/shared/config/resque-pool.yml` on your utility
|
|
119
|
+
servers). Even if you don't use chef, you can still use the example init.d
|
|
120
|
+
script and monitrc (erb templates) provided in
|
|
121
|
+
`examples/chef_cookbook/templates/default`.
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
them.
|
|
123
|
+
You can also start a pool manager via `rake resque:pool` or from a plain old
|
|
124
|
+
ruby script by calling `Resque::Pool.run`.
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
Workers will watch the pool manager, and gracefully shutdown (after completing
|
|
127
|
+
their current job) if the manager process disappears before them.
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
You can specify an alternate config file by setting the `RESQUE_POOL_CONFIG` or
|
|
130
|
+
with the `--config` command line option.
|
|
129
131
|
|
|
130
132
|
TODO
|
|
131
133
|
-----
|
|
132
134
|
|
|
133
|
-
* cmd line option for non-rake loading
|
|
134
|
-
* cmd line option for preload ruby file
|
|
135
|
-
* provide Unix style log formatter
|
|
136
135
|
* web interface for adding and removing workers (etc)
|
|
136
|
+
* config file split by hostname
|
|
137
|
+
* rename to `resque-squad`?
|
|
138
|
+
* cmd line option for non-rake loading
|
|
139
|
+
* cmd line option for preloading ruby file
|
|
140
|
+
* provide Unix style log formatter (compatible with $stdout/$stderr)
|
|
137
141
|
* recover gracefully from a malformed config file (on startup and HUP)
|
|
138
|
-
* procline for malformed config file, graceful shutdown... and other states?
|
|
142
|
+
* change procline for malformed config file, graceful shutdown... and other states?
|
|
139
143
|
* figure out a good automated way to test this (cucumber or rspec?)
|
|
140
144
|
* clean up the code (I stole most of it from unicorn, and it's still a bit
|
|
141
|
-
bastardized); excessive use of vim foldmarkers are a code smell
|
|
142
|
-
* rename to `resque-squad`?
|
|
145
|
+
bastardized); excessive use of vim foldmarkers are a code smell!
|
|
143
146
|
* rdoc
|
|
144
|
-
* incorporate resque-batchworker features? (v2.0)
|
|
147
|
+
* integrate with or incorporate resque-batchworker features? (v2.0)
|
|
148
|
+
* integrate with resque-scheduler? (v2.0)
|
|
145
149
|
|
|
146
150
|
Contributors
|
|
147
151
|
-------------
|
|
148
152
|
|
|
149
153
|
* John Schult (config file can be split by environment)
|
|
150
154
|
* Stephen Celis (increased gemspec sanity)
|
|
155
|
+
* Vincent Agnello, Robert Kamunyori, Paul Kauders; for pairing with me at
|
|
156
|
+
B'more on Rails Open Source Hack Nights. :)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
roles = %w[solo util]
|
|
2
|
+
if roles.include?(node[:instance_role])
|
|
2
3
|
node[:applications].each do |app, data|
|
|
3
4
|
|
|
5
|
+
pidfile = "/data/#{app}/current/tmp/pids/#{app}_resque.pid"
|
|
6
|
+
|
|
4
7
|
template "/etc/monit.d/#{app}_resque.monitrc" do
|
|
5
8
|
owner 'root'
|
|
6
9
|
group 'root'
|
|
@@ -8,6 +11,7 @@ if ['solo', 'util'].include?(node[:instance_role])
|
|
|
8
11
|
source "monitrc.erb"
|
|
9
12
|
variables({
|
|
10
13
|
:app_name => app,
|
|
14
|
+
:pidfile => pidfile,
|
|
11
15
|
#:max_mem => "400 MB",
|
|
12
16
|
})
|
|
13
17
|
end
|
|
@@ -16,9 +20,10 @@ if ['solo', 'util'].include?(node[:instance_role])
|
|
|
16
20
|
owner 'root'
|
|
17
21
|
group 'root'
|
|
18
22
|
mode 0744
|
|
19
|
-
source "initd.
|
|
23
|
+
source "initd.erb"
|
|
20
24
|
variables({
|
|
21
25
|
:app_name => app,
|
|
26
|
+
:pidfile => pidfile,
|
|
22
27
|
})
|
|
23
28
|
end
|
|
24
29
|
|
|
@@ -30,6 +35,7 @@ if ['solo', 'util'].include?(node[:instance_role])
|
|
|
30
35
|
|
|
31
36
|
execute "start-resque" do
|
|
32
37
|
command %Q{/etc/init.d/#{app}_resque start}
|
|
38
|
+
creates pidfile
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
execute "ensure-resque-is-setup-with-monit" do
|
|
@@ -13,19 +13,24 @@
|
|
|
13
13
|
### END INIT INFO
|
|
14
14
|
|
|
15
15
|
# configure these values here or in /etc/default/resque-pool
|
|
16
|
+
# make sure your pidfile here matches your monitrc
|
|
16
17
|
app_name="<%= @app_name %>"
|
|
18
|
+
pidfile="<%= @pidfile %>"
|
|
17
19
|
app_dir="/data/${app_name}/current"
|
|
18
20
|
run_as_user="deploy"
|
|
19
|
-
pidfile="/var/run/resque-pool-${app_name}.pid"
|
|
20
21
|
sleep_time_during_restart=5
|
|
21
|
-
|
|
22
|
+
stop_schedule="QUIT/30/INT/10/KILL/5"
|
|
23
|
+
bundler="/usr/bin/bundle"
|
|
22
24
|
environment="production"
|
|
23
25
|
stdout_log="${app_dir}/log/resque-pool-${app_name}.stdout.log"
|
|
24
26
|
stderr_log="${app_dir}/log/resque-pool-${app_name}.stderr.log"
|
|
25
27
|
|
|
26
28
|
# override above values, and set any other env variables you need
|
|
27
|
-
if [ -f /etc/default/resque
|
|
28
|
-
. /etc/default/resque
|
|
29
|
+
if [ -f /etc/default/resque ] ; then
|
|
30
|
+
. /etc/default/resque
|
|
31
|
+
fi
|
|
32
|
+
if [ -f /etc/default/${app_name}_resque ] ; then
|
|
33
|
+
. /etc/default/${app_name}_resque
|
|
29
34
|
fi
|
|
30
35
|
|
|
31
36
|
case "$1" in
|
|
@@ -38,6 +43,9 @@ case "$1" in
|
|
|
38
43
|
--startas ${bundler} -- exec \
|
|
39
44
|
resque-pool -d -p ${pidfile} -E ${environment} -o ${stdout_log} -e ${stderr_log}
|
|
40
45
|
;;
|
|
46
|
+
reload)
|
|
47
|
+
start-stop-daemon --stop --pidfile ${pidfile} --signal HUP
|
|
48
|
+
;;
|
|
41
49
|
graceful-stop)
|
|
42
50
|
start-stop-daemon --stop --pidfile ${pidfile} --signal QUIT
|
|
43
51
|
;;
|
|
@@ -45,7 +53,7 @@ case "$1" in
|
|
|
45
53
|
start-stop-daemon --stop --pidfile ${pidfile} --signal INT
|
|
46
54
|
;;
|
|
47
55
|
stop)
|
|
48
|
-
start-stop-daemon --stop --pidfile ${pidfile} --
|
|
56
|
+
start-stop-daemon --stop --pidfile ${pidfile} --retry=${stop_schedule}
|
|
49
57
|
;;
|
|
50
58
|
restart)
|
|
51
59
|
$0 stop
|
|
@@ -53,7 +61,7 @@ case "$1" in
|
|
|
53
61
|
$0 start
|
|
54
62
|
;;
|
|
55
63
|
*)
|
|
56
|
-
echo "Usage: $0 {start|stop|graceful-stop|quick-stop|restart}"
|
|
64
|
+
echo "Usage: $0 {start|stop|graceful-stop|quick-stop|restart|reload}"
|
|
57
65
|
exit 1
|
|
58
66
|
;;
|
|
59
67
|
esac
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
check process <%= @app_name %>_resque
|
|
2
|
-
with pidfile
|
|
3
|
-
start program = "/etc/init.d/<%= @app_name %>_resque start" with timeout 90 seconds
|
|
2
|
+
with pidfile <%= @pidfile %>
|
|
3
|
+
start program = "/etc/init.d/<%= @app_name %>_resque start" with timeout 90 seconds
|
|
4
4
|
stop program = "/etc/init.d/<%= @app_name %>_resque stop" with timeout 90 seconds
|
|
5
5
|
#if totalmem is greater than <%= @max_mem || "300 MB" %> for 10 cycles then restart # eating up memory?
|
|
6
6
|
group resque
|
data/lib/resque/pool/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resque-pool
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
5
|
-
prerelease:
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
|
-
- 0
|
|
9
|
-
- 12
|
|
10
8
|
- 1
|
|
11
|
-
-
|
|
12
|
-
version: 0.
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
13
11
|
platform: ruby
|
|
14
12
|
authors:
|
|
15
13
|
- nicholas a. evans
|
|
@@ -17,7 +15,7 @@ autorequire:
|
|
|
17
15
|
bindir: bin
|
|
18
16
|
cert_chain: []
|
|
19
17
|
|
|
20
|
-
date: 2011-01-
|
|
18
|
+
date: 2011-01-18 00:00:00 -05:00
|
|
21
19
|
default_executable:
|
|
22
20
|
dependencies:
|
|
23
21
|
- !ruby/object:Gem::Dependency
|
|
@@ -118,6 +116,7 @@ extra_rdoc_files: []
|
|
|
118
116
|
|
|
119
117
|
files:
|
|
120
118
|
- .gitignore
|
|
119
|
+
- Changelog.md
|
|
121
120
|
- Gemfile
|
|
122
121
|
- Gemfile.lock
|
|
123
122
|
- LICENSE.txt
|
|
@@ -164,14 +163,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
164
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
164
|
none: false
|
|
166
165
|
requirements:
|
|
167
|
-
- - "
|
|
166
|
+
- - ">="
|
|
168
167
|
- !ruby/object:Gem::Version
|
|
169
|
-
hash:
|
|
168
|
+
hash: 3
|
|
170
169
|
segments:
|
|
171
|
-
-
|
|
172
|
-
|
|
173
|
-
- 1
|
|
174
|
-
version: 1.3.1
|
|
170
|
+
- 0
|
|
171
|
+
version: "0"
|
|
175
172
|
requirements: []
|
|
176
173
|
|
|
177
174
|
rubyforge_project:
|