resque-ranger 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/bin/resque-ranger +7 -5
- data/lib/raemon/runner.rb +73 -0
- data/lib/resque/runner.rb +3 -3
- data/resque-ranger.gemspec +4 -4
- metadata +17 -4
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= resque-ranger
|
2
2
|
|
3
|
-
|
3
|
+
So basically I patched raemon and resque so that it will have on master process that will forks n number of child processes for jobs on the queue. Each worker will still exit after it finishes the job, so you still get the benefits from that aspect of the way resque handles jobs. I eventually plan to switch all of the redis interaction to an evented model and maybe even add fibers. I also plan to add some stats around job execution time so you can keep track of over all performance benefits.
|
4
4
|
|
5
5
|
== Note on Patches/Pull Requests
|
6
6
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/bin/resque-ranger
CHANGED
@@ -104,7 +104,7 @@ Choice.options do
|
|
104
104
|
long '--pid_file'
|
105
105
|
desc 'Path to the pid file'
|
106
106
|
cast String
|
107
|
-
default
|
107
|
+
default 'tmp/pids/resque-ranger.pid'
|
108
108
|
end
|
109
109
|
|
110
110
|
separator ''
|
@@ -118,8 +118,10 @@ end
|
|
118
118
|
|
119
119
|
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = Choice.choices[:environment]
|
120
120
|
|
121
|
+
Resque.redis = Redis.new(Choice.choices[:redis])
|
122
|
+
|
121
123
|
Raemon::Runner.queues = Choice.choices[:queues]
|
122
|
-
Raemon::Runner.start
|
123
|
-
|
124
|
-
|
125
|
-
|
124
|
+
Raemon::Runner.start Choice.choices[:workers], Resque::Ranger, :detach => @detach,
|
125
|
+
:timeout => Choice.choices[:timeout],
|
126
|
+
:logger => Choice.choices[:logger],
|
127
|
+
:pid_file => Choice.choices[:pid_file]
|
data/lib/raemon/runner.rb
CHANGED
@@ -18,5 +18,78 @@ module Raemon
|
|
18
18
|
super
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
# monitors children and receives signals forever
|
23
|
+
# (or until a termination signal is sent). This handles signals
|
24
|
+
# one-at-a-time time and we'll happily drop signals in case somebody
|
25
|
+
# is signalling us too often.
|
26
|
+
def master_loop!
|
27
|
+
# this pipe is used to wake us up from select(2) in #join when signals
|
28
|
+
# are trapped. See trap_deferred
|
29
|
+
init_self_pipe!
|
30
|
+
@respawn = true
|
31
|
+
|
32
|
+
QUEUE_SIGS.each { |sig| trap_deferred(sig) }
|
33
|
+
trap(:CHLD) { |sig_nr| awaken_master }
|
34
|
+
|
35
|
+
process_name 'master'
|
36
|
+
logger.info "master process ready"
|
37
|
+
|
38
|
+
# Spawn workers for the first time
|
39
|
+
maintain_worker_count
|
40
|
+
|
41
|
+
begin
|
42
|
+
loop do
|
43
|
+
monitor_memory_usage
|
44
|
+
reap_all_workers
|
45
|
+
|
46
|
+
case SIG_QUEUE.shift
|
47
|
+
when nil
|
48
|
+
murder_lazy_workers
|
49
|
+
maintain_worker_count if @respawn
|
50
|
+
master_sleep
|
51
|
+
when :QUIT # graceful shutdown
|
52
|
+
break
|
53
|
+
when :TERM, :INT # immediate shutdown
|
54
|
+
stop(false)
|
55
|
+
break
|
56
|
+
when :USR1
|
57
|
+
kill_each_worker(:USR1)
|
58
|
+
when :USR2
|
59
|
+
kill_each_worker(:USR2)
|
60
|
+
when :WINCH
|
61
|
+
if Process.ppid == 1 || Process.getpgrp != $$
|
62
|
+
@respawn = false
|
63
|
+
logger.info "gracefully stopping all workers"
|
64
|
+
kill_each_worker(:QUIT)
|
65
|
+
else
|
66
|
+
logger.info "SIGWINCH ignored because we're not daemonized"
|
67
|
+
end
|
68
|
+
when :TTIN
|
69
|
+
@num_workers += 1
|
70
|
+
when :TTOU
|
71
|
+
@num_workers -= 1 if @num_workers > 0
|
72
|
+
when :HUP
|
73
|
+
# TODO: should restart the workers, but a :QUIT could stall
|
74
|
+
# respawn = true
|
75
|
+
# kill_each_worker(:QUIT)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
rescue Errno::EINTR
|
79
|
+
retry
|
80
|
+
rescue => ex
|
81
|
+
logger.error "Unhandled master loop exception #{ex.inspect}."
|
82
|
+
logger.error ex.backtrace.join("\n")
|
83
|
+
retry
|
84
|
+
end
|
85
|
+
|
86
|
+
# Gracefully shutdown all workers on our way out
|
87
|
+
stop
|
88
|
+
logger.info "master complete"
|
89
|
+
|
90
|
+
# Close resources
|
91
|
+
unlink_pid_safe(pid_file) if pid_file
|
92
|
+
logger.close
|
93
|
+
end
|
21
94
|
end
|
22
95
|
end
|
data/lib/resque/runner.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Resque
|
2
2
|
class Runner < Worker
|
3
3
|
def work(interval = 5, &block)
|
4
|
-
$0 = "resque: Starting"
|
4
|
+
$0 = "resque: Starting - #{Process.pid}"
|
5
5
|
startup
|
6
6
|
|
7
7
|
if not @paused and job = reserve
|
@@ -9,7 +9,7 @@ module Resque
|
|
9
9
|
run_hook :before_fork
|
10
10
|
working_on job
|
11
11
|
|
12
|
-
procline "Processing #{job.queue} since #{Time.now.to_i}"
|
12
|
+
procline "Processing #{job.queue} since #{Time.now.to_i} - #{Process.pid}"
|
13
13
|
perform(job, &block)
|
14
14
|
exit! unless @cant_fork
|
15
15
|
|
@@ -17,7 +17,7 @@ module Resque
|
|
17
17
|
@child = nil
|
18
18
|
else
|
19
19
|
break if interval.to_i == 0
|
20
|
-
log! "Sleeping for #{interval.to_i}"
|
20
|
+
log! "Sleeping for #{interval.to_i} - #{Process.pid}"
|
21
21
|
procline @paused ? "Paused" : "Waiting for #{@queues.join(',')}"
|
22
22
|
sleep interval.to_i
|
23
23
|
end
|
data/resque-ranger.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{resque-ranger}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["brianthecoder"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-06-02}
|
13
13
|
s.default_executable = %q{resque-ranger}
|
14
14
|
s.description = %q{Super fast evented daemon to process resque jobs, some built in job metrics too, just cause your app might not be on 1.9.1, your bot might be able to}
|
15
15
|
s.email = %q{wbsmith83@gmail.com}
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |s|
|
|
37
37
|
s.homepage = %q{http://github.com/BrianTheCoder/resque-ranger}
|
38
38
|
s.rdoc_options = ["--charset=UTF-8"]
|
39
39
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version = %q{1.3.
|
40
|
+
s.rubygems_version = %q{1.3.7}
|
41
41
|
s.summary = %q{Super fast evented daemon to process resque jobs, some built in job metrics too}
|
42
42
|
s.test_files = [
|
43
43
|
"test/helper.rb",
|
@@ -48,7 +48,7 @@ Gem::Specification.new do |s|
|
|
48
48
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
49
|
s.specification_version = 3
|
50
50
|
|
51
|
-
if Gem::Version.new(Gem::
|
51
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
52
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
53
53
|
s.add_runtime_dependency(%q<redis>, ["= 1.0.4"])
|
54
54
|
s.add_runtime_dependency(%q<resque>, ["= 1.8.0"])
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-ranger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- brianthecoder
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-06-02 00:00:00 -05:00
|
18
19
|
default_executable: resque-ranger
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: thoughtbot-shoulda
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
version: "0"
|
@@ -33,9 +36,11 @@ dependencies:
|
|
33
36
|
name: redis
|
34
37
|
prerelease: false
|
35
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
36
40
|
requirements:
|
37
41
|
- - "="
|
38
42
|
- !ruby/object:Gem::Version
|
43
|
+
hash: 31
|
39
44
|
segments:
|
40
45
|
- 1
|
41
46
|
- 0
|
@@ -47,9 +52,11 @@ dependencies:
|
|
47
52
|
name: resque
|
48
53
|
prerelease: false
|
49
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
50
56
|
requirements:
|
51
57
|
- - "="
|
52
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 55
|
53
60
|
segments:
|
54
61
|
- 1
|
55
62
|
- 8
|
@@ -61,9 +68,11 @@ dependencies:
|
|
61
68
|
name: eventmachine
|
62
69
|
prerelease: false
|
63
70
|
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
64
72
|
requirements:
|
65
73
|
- - "="
|
66
74
|
- !ruby/object:Gem::Version
|
75
|
+
hash: 47
|
67
76
|
segments:
|
68
77
|
- 0
|
69
78
|
- 12
|
@@ -105,23 +114,27 @@ rdoc_options:
|
|
105
114
|
require_paths:
|
106
115
|
- lib
|
107
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
108
118
|
requirements:
|
109
119
|
- - ">="
|
110
120
|
- !ruby/object:Gem::Version
|
121
|
+
hash: 3
|
111
122
|
segments:
|
112
123
|
- 0
|
113
124
|
version: "0"
|
114
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
115
127
|
requirements:
|
116
128
|
- - ">="
|
117
129
|
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
118
131
|
segments:
|
119
132
|
- 0
|
120
133
|
version: "0"
|
121
134
|
requirements: []
|
122
135
|
|
123
136
|
rubyforge_project:
|
124
|
-
rubygems_version: 1.3.
|
137
|
+
rubygems_version: 1.3.7
|
125
138
|
signing_key:
|
126
139
|
specification_version: 3
|
127
140
|
summary: Super fast evented daemon to process resque jobs, some built in job metrics too
|