resque-multi-job-forks 0.4.3 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/resque-multi-job-forks.rb +48 -23
- data/test/helper.rb +12 -34
- data/test/test_resque-multi-job-forks.rb +98 -21
- data/test/test_rss_reader.rb +5 -2
- metadata +29 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2b710d8dc861eb050596364959ae65da3f099c29492370d3a817239428cf5a38
|
4
|
+
data.tar.gz: 45b5e45ddf6aac1a092b5d9047483ad4b9d4064920d5f875f8251686310e2d46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d98283d9a0b31141e943d452cf786781c5b6e3e42dbacc2a7175a41e8f4380bc85914570215111c1a088ed16e6f9d08855cba454ca943e75eac09694f0d8da2
|
7
|
+
data.tar.gz: 6199e71957234fe7c374778ddb28e56207e9c438750eb2051852f0bd150cb89304c587351e007d76eb680ed0a09c42fcb6e52ef0f7f3c99eaae84e9e2a7d06a4
|
@@ -15,7 +15,30 @@ module Resque
|
|
15
15
|
end
|
16
16
|
|
17
17
|
if multi_jobs_per_fork? && !method_defined?(:shutdown_without_multi_job_forks)
|
18
|
+
|
19
|
+
def fork(&block)
|
20
|
+
if child = Kernel.fork
|
21
|
+
return child
|
22
|
+
else
|
23
|
+
if term_child
|
24
|
+
unregister_signal_handlers
|
25
|
+
trap('QUIT') { shutdown }
|
26
|
+
end
|
27
|
+
raise NotImplementedError, "Pretending to not have forked"
|
28
|
+
# perform_with_fork will run the job and continue working...
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def work_with_multi_job_forks(*args)
|
33
|
+
pid # forces @pid to be set in the parent
|
34
|
+
work_without_multi_job_forks(*args)
|
35
|
+
release_and_exit! unless is_parent_process?
|
36
|
+
end
|
37
|
+
alias_method :work_without_multi_job_forks, :work
|
38
|
+
alias_method :work, :work_with_multi_job_forks
|
39
|
+
|
18
40
|
def perform_with_multi_job_forks(job = nil)
|
41
|
+
@fork_per_job = true unless fork_hijacked? # reconnect and after_fork
|
19
42
|
perform_without_multi_job_forks(job)
|
20
43
|
hijack_fork unless fork_hijacked?
|
21
44
|
@jobs_processed += 1
|
@@ -31,15 +54,15 @@ module Resque
|
|
31
54
|
alias_method :shutdown?, :shutdown_with_multi_job_forks?
|
32
55
|
|
33
56
|
def shutdown_with_multi_job_forks
|
57
|
+
shutdown_child
|
34
58
|
shutdown_without_multi_job_forks
|
35
|
-
shutdown_child if is_parent_process?
|
36
59
|
end
|
37
60
|
alias_method :shutdown_without_multi_job_forks, :shutdown
|
38
61
|
alias_method :shutdown, :shutdown_with_multi_job_forks
|
39
62
|
|
40
63
|
def pause_processing_with_multi_job_forks
|
64
|
+
shutdown_child
|
41
65
|
pause_processing_without_multi_job_forks
|
42
|
-
shutdown_child if is_parent_process?
|
43
66
|
end
|
44
67
|
alias_method :pause_processing_without_multi_job_forks, :pause_processing
|
45
68
|
alias_method :pause_processing, :pause_processing_with_multi_job_forks
|
@@ -49,7 +72,7 @@ module Resque
|
|
49
72
|
working_on_without_worker_registration(job)
|
50
73
|
end
|
51
74
|
alias_method :working_on_without_worker_registration, :working_on
|
52
|
-
alias_method :working_on, :working_on_with_worker_registration
|
75
|
+
alias_method :working_on, :working_on_with_worker_registration
|
53
76
|
|
54
77
|
# Reconnect only once
|
55
78
|
def reconnect_with_multi_job_forks
|
@@ -62,18 +85,26 @@ module Resque
|
|
62
85
|
alias_method :reconnect, :reconnect_with_multi_job_forks
|
63
86
|
end
|
64
87
|
|
65
|
-
# Need to tell the child to shutdown since it might be looping performing
|
66
|
-
#
|
88
|
+
# Need to tell the child to shutdown since it might be looping performing
|
89
|
+
# multiple jobs per fork. The QUIT signal normally does a graceful shutdown,
|
90
|
+
# and is re-registered in children (term_child normally unregisters it).
|
67
91
|
def shutdown_child
|
92
|
+
return unless @child
|
68
93
|
begin
|
69
|
-
|
94
|
+
log_with_severity :debug, "multi_jobs_per_fork: Sending QUIT signal to #{@child}"
|
95
|
+
Process.kill('QUIT', @child)
|
70
96
|
rescue Errno::ESRCH
|
71
97
|
nil
|
72
98
|
end
|
73
99
|
end
|
74
100
|
|
75
101
|
def is_parent_process?
|
76
|
-
@child
|
102
|
+
@child || @pid == Process.pid
|
103
|
+
end
|
104
|
+
|
105
|
+
def release_and_exit!
|
106
|
+
release_fork if fork_hijacked?
|
107
|
+
run_at_exit_hooks ? exit : exit!(true)
|
77
108
|
end
|
78
109
|
|
79
110
|
def fork_hijacked?
|
@@ -81,26 +112,25 @@ module Resque
|
|
81
112
|
end
|
82
113
|
|
83
114
|
def hijack_fork
|
84
|
-
|
115
|
+
log_with_severity :debug, 'hijack fork.'
|
85
116
|
@suppressed_fork_hooks = [Resque.after_fork, Resque.before_fork]
|
86
117
|
Resque.after_fork = Resque.before_fork = nil
|
87
118
|
@release_fork_limit = fork_job_limit
|
88
119
|
@jobs_processed = 0
|
89
|
-
@
|
90
|
-
trap('TSTP') { shutdown }
|
120
|
+
@fork_per_job = false
|
91
121
|
end
|
92
122
|
|
93
123
|
def release_fork
|
94
|
-
|
124
|
+
log_with_severity :info, "jobs processed by child: #{jobs_processed}; rss: #{rss}"
|
95
125
|
run_hook :before_child_exit, self
|
96
126
|
Resque.after_fork, Resque.before_fork = *@suppressed_fork_hooks
|
97
|
-
@release_fork_limit = @jobs_processed =
|
98
|
-
|
99
|
-
@shutdown = true
|
127
|
+
@release_fork_limit = @jobs_processed = nil
|
128
|
+
log_with_severity :debug, 'hijack over, counter terrorists win.'
|
129
|
+
@shutdown = true
|
100
130
|
end
|
101
131
|
|
102
132
|
def fork_job_limit
|
103
|
-
jobs_per_fork.nil? ? Time.now.
|
133
|
+
jobs_per_fork.nil? ? Time.now.to_f + seconds_per_fork : jobs_per_fork
|
104
134
|
end
|
105
135
|
|
106
136
|
def fork_job_limit_reached?
|
@@ -108,7 +138,7 @@ module Resque
|
|
108
138
|
end
|
109
139
|
|
110
140
|
def fork_job_limit_remaining
|
111
|
-
jobs_per_fork.nil? ? @release_fork_limit - Time.now.
|
141
|
+
jobs_per_fork.nil? ? @release_fork_limit - Time.now.to_f : jobs_per_fork - @jobs_processed
|
112
142
|
end
|
113
143
|
|
114
144
|
def seconds_per_fork
|
@@ -140,16 +170,11 @@ module Resque
|
|
140
170
|
# Call with a block to set the hook.
|
141
171
|
# Call with no arguments to return the hook.
|
142
172
|
def self.before_child_exit(&block)
|
143
|
-
|
144
|
-
@before_child_exit ||= []
|
145
|
-
@before_child_exit << block
|
146
|
-
end
|
147
|
-
@before_child_exit
|
173
|
+
block ? register_hook(:before_child_exit, block) : hooks(:before_child_exit)
|
148
174
|
end
|
149
175
|
|
150
176
|
# Set the before_child_exit proc.
|
151
177
|
def self.before_child_exit=(before_child_exit)
|
152
|
-
|
178
|
+
register_hook(:before_child_exit, block)
|
153
179
|
end
|
154
|
-
|
155
180
|
end
|
data/test/helper.rb
CHANGED
@@ -12,72 +12,50 @@ require 'resque-multi-job-forks'
|
|
12
12
|
require 'timeout'
|
13
13
|
|
14
14
|
# setup redis & resque.
|
15
|
-
redis = Redis.new(:db => 1)
|
16
|
-
Resque.redis = redis
|
15
|
+
$redis = Redis.new(:db => 1)
|
16
|
+
Resque.redis = $redis
|
17
17
|
|
18
18
|
# adds simple STDOUT logging to test workers.
|
19
19
|
# set `VERBOSE=true` when running the tests to view resques log output.
|
20
20
|
module Resque
|
21
21
|
class Worker
|
22
|
-
def log(msg)
|
23
|
-
puts "*** #{msg}" unless ENV['VERBOSE'].nil?
|
24
|
-
end
|
25
|
-
alias_method :log!, :log
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# if the :after_fork hook runs, we ignore 'will_fork?' here.
|
32
|
-
run_hook :after_fork, job # if will_fork?
|
33
|
-
job.perform
|
34
|
-
rescue Object => e
|
35
|
-
log "#{job.inspect} failed: #{e.inspect}"
|
36
|
-
begin
|
37
|
-
job.fail(e)
|
38
|
-
rescue Object => e
|
39
|
-
log "Received exception when reporting failure: #{e.inspect}"
|
40
|
-
end
|
41
|
-
failed!
|
42
|
-
else
|
43
|
-
log "done: #{job.inspect}"
|
44
|
-
ensure
|
45
|
-
yield job if block_given?
|
23
|
+
def log_with_severity(severity, msg)
|
24
|
+
if ENV['VERBOSE']
|
25
|
+
s = severity.to_s[0].upcase
|
26
|
+
$stderr.print "*** [#{Time.now}] [#{Process.pid}] #{self} #{s}: #{msg}\n"
|
46
27
|
end
|
47
28
|
end
|
29
|
+
|
48
30
|
end
|
49
31
|
end
|
50
32
|
|
51
|
-
# stores a record of the job processing sequence.
|
52
|
-
# you may wish to reset this in the test `setup` method.
|
53
|
-
$SEQUENCE = []
|
54
|
-
|
55
33
|
# test job, tracks sequence.
|
56
34
|
class SequenceJob
|
57
35
|
@queue = :jobs
|
58
36
|
def self.perform(i)
|
59
|
-
$SEQUENCE << "work_#{i}".to_sym
|
60
37
|
sleep(2)
|
38
|
+
$SEQ_WRITER.print "work_#{i}\n"
|
61
39
|
end
|
62
40
|
end
|
63
41
|
|
64
42
|
class QuickSequenceJob
|
65
43
|
@queue = :jobs
|
66
44
|
def self.perform(i)
|
67
|
-
$
|
45
|
+
$SEQ_WRITER.print "work_#{i}\n"
|
68
46
|
end
|
69
47
|
end
|
70
48
|
|
71
49
|
|
72
50
|
# test hooks, tracks sequence.
|
73
51
|
Resque.after_fork do
|
74
|
-
$
|
52
|
+
$SEQ_WRITER.print "after_fork\n"
|
75
53
|
end
|
76
54
|
|
77
55
|
Resque.before_fork do
|
78
|
-
$
|
56
|
+
$SEQ_WRITER.print "before_fork\n"
|
79
57
|
end
|
80
58
|
|
81
59
|
Resque.before_child_exit do |worker|
|
82
|
-
$
|
60
|
+
$SEQ_WRITER.print "before_child_exit_#{worker.jobs_processed}\n"
|
83
61
|
end
|
@@ -2,12 +2,13 @@ require File.join(File.expand_path(File.dirname(__FILE__)), '/helper')
|
|
2
2
|
|
3
3
|
class TestResqueMultiJobForks < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
$
|
6
|
-
|
5
|
+
$SEQ_READER, $SEQ_WRITER = IO.pipe
|
6
|
+
$redis.flushdb
|
7
7
|
@worker = Resque::Worker.new(:jobs)
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_timeout_limit_sequence_of_events
|
11
|
+
@worker.log_with_severity :debug, "in test_timeout_limit_sequence_of_events"
|
11
12
|
# only allow enough time for 3 jobs to process.
|
12
13
|
@worker.seconds_per_fork = 3
|
13
14
|
|
@@ -16,43 +17,119 @@ class TestResqueMultiJobForks < Test::Unit::TestCase
|
|
16
17
|
Resque.enqueue(SequenceJob, 3)
|
17
18
|
Resque.enqueue(SequenceJob, 4)
|
18
19
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
20
|
+
# INTERVAL=0 will exit when no more jobs left
|
21
|
+
@worker.work(0)
|
22
|
+
$SEQ_WRITER.close
|
23
|
+
sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
|
24
24
|
|
25
25
|
# test the sequence is correct.
|
26
26
|
assert_equal([:before_fork, :after_fork, :work_1, :work_2, :work_3,
|
27
27
|
:before_child_exit_3, :before_fork, :after_fork, :work_4,
|
28
|
-
:before_child_exit_1],
|
28
|
+
:before_child_exit_1], sequence, 'correct sequence')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_graceful_shutdown_during_first_job
|
32
|
+
@worker.log_with_severity :debug, "in test_graceful_shutdown_during_first_job"
|
33
|
+
# enough time for all jobs to process.
|
34
|
+
@worker.seconds_per_fork = 60
|
35
|
+
|
36
|
+
Resque.enqueue(SequenceJob, 1)
|
37
|
+
Resque.enqueue(SequenceJob, 2)
|
38
|
+
t = Thread.new do
|
39
|
+
sleep 1 # before first job can complete
|
40
|
+
@worker.shutdown
|
41
|
+
end
|
42
|
+
# INTERVAL=0 will exit when no more jobs left
|
43
|
+
@worker.work(0)
|
44
|
+
$SEQ_WRITER.close
|
45
|
+
sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
|
46
|
+
|
47
|
+
# test the sequence is correct.
|
48
|
+
assert_equal([:before_fork, :after_fork, :work_1,
|
49
|
+
:before_child_exit_1], sequence, 'correct sequence')
|
50
|
+
t.join
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_immediate_shutdown_during_first_job
|
54
|
+
@worker.log_with_severity :debug, "in test_immediate_shutdown_during_first_job"
|
55
|
+
# enough time for all jobs to process.
|
56
|
+
@worker.seconds_per_fork = 60
|
57
|
+
@worker.term_child = false
|
58
|
+
|
59
|
+
Resque.enqueue(SequenceJob, 1)
|
60
|
+
Resque.enqueue(SequenceJob, 2)
|
61
|
+
t = Thread.new do
|
62
|
+
sleep 0.5 # before first job can complete
|
63
|
+
Process.kill("INT", @worker.pid) # triggers shutdown! in main thread
|
64
|
+
end
|
65
|
+
# INTERVAL=0 will exit when no more jobs left
|
66
|
+
@worker.work(0)
|
67
|
+
$SEQ_WRITER.close
|
68
|
+
sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
|
69
|
+
|
70
|
+
# test the sequence is correct.
|
71
|
+
assert_equal([:before_fork, :after_fork], sequence, 'correct sequence')
|
72
|
+
t.join
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_sigterm_shutdown_during_first_job
|
76
|
+
@worker.log_with_severity :debug, "in test_sigterm_shutdown_during_first_job"
|
77
|
+
# enough time for all jobs to process.
|
78
|
+
@worker.seconds_per_fork = 60
|
79
|
+
@worker.term_child = true
|
80
|
+
@worker.term_timeout = 0.5
|
81
|
+
|
82
|
+
Resque.enqueue(SequenceJob, 1)
|
83
|
+
Resque.enqueue(SequenceJob, 2)
|
84
|
+
t = Thread.new do
|
85
|
+
sleep 1.0 # before first job can complete
|
86
|
+
Process.kill("INT", @worker.pid) # triggers shutdown! in main thread
|
87
|
+
end
|
88
|
+
# INTERVAL=0 will exit when no more jobs left
|
89
|
+
@worker.work(0)
|
90
|
+
$SEQ_WRITER.close
|
91
|
+
sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
|
92
|
+
|
93
|
+
# test the sequence is correct.
|
94
|
+
assert_equal([:before_fork, :after_fork,
|
95
|
+
:before_child_exit_1], sequence, 'correct sequence')
|
96
|
+
t.join
|
29
97
|
end
|
30
98
|
|
31
99
|
# test we can also limit fork job process by a job limit.
|
32
100
|
def test_job_limit_sequence_of_events
|
33
|
-
|
101
|
+
@worker.log_with_severity :debug, "in test_job_limit_sequence_of_events"
|
102
|
+
# only allow 20 jobs per fork
|
34
103
|
ENV['JOBS_PER_FORK'] = '20'
|
35
104
|
|
36
105
|
# queue 40 jobs.
|
37
106
|
(1..40).each { |i| Resque.enqueue(QuickSequenceJob, i) }
|
38
107
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
108
|
+
# INTERVAL=0 will exit when no more jobs left
|
109
|
+
@worker.work(0)
|
110
|
+
$SEQ_WRITER.close
|
111
|
+
sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
|
43
112
|
|
44
|
-
assert_equal
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
113
|
+
assert_equal(%i[
|
114
|
+
before_fork after_fork
|
115
|
+
work_1 work_2 work_3 work_4 work_5
|
116
|
+
work_6 work_7 work_8 work_9 work_10
|
117
|
+
work_11 work_12 work_13 work_14 work_15
|
118
|
+
work_16 work_17 work_18 work_19 work_20
|
119
|
+
before_child_exit_20
|
120
|
+
before_fork after_fork
|
121
|
+
work_21 work_22 work_23 work_24 work_25
|
122
|
+
work_26 work_27 work_28 work_29 work_30
|
123
|
+
work_31 work_32 work_33 work_34 work_35
|
124
|
+
work_36 work_37 work_38 work_39 work_40
|
125
|
+
before_child_exit_20
|
126
|
+
], sequence, 'correct sequence')
|
52
127
|
end
|
53
128
|
|
54
129
|
def teardown
|
55
130
|
# make sure we don't clobber any other tests.
|
56
131
|
ENV['JOBS_PER_FORK'] = nil
|
132
|
+
Resque::Worker.kill_all_heartbeat_threads
|
57
133
|
end
|
134
|
+
|
58
135
|
end
|
data/test/test_rss_reader.rb
CHANGED
@@ -7,17 +7,20 @@ class TestRssReader < Test::Unit::TestCase
|
|
7
7
|
@object.extend Resque::Plugins::MultiJobForks::RssReader
|
8
8
|
end
|
9
9
|
|
10
|
+
# support before/after ruby 2.4 without deprecation notice
|
11
|
+
IntegerClass = 1.class
|
12
|
+
|
10
13
|
def test_current_process_rss
|
11
14
|
rss = @object.rss
|
12
15
|
# not a very strict test, but have you ever seen a ruby process < 1Mb?
|
13
16
|
# the "real" test is manual verification via top/ps/htop
|
14
|
-
assert_equal
|
17
|
+
assert_equal IntegerClass, rss.class
|
15
18
|
assert @object.rss > 1000
|
16
19
|
end
|
17
20
|
|
18
21
|
def test_rss_other_processes
|
19
22
|
rss = @object.rss(1) # init is guaranteed to exist
|
20
|
-
assert_equal
|
23
|
+
assert_equal IntegerClass, rss.class
|
21
24
|
assert @object.rss > 1000
|
22
25
|
end
|
23
26
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-multi-job-forks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mick Staugaard
|
@@ -10,22 +10,28 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: resque
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - "
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.27.0
|
22
|
+
- - "<"
|
20
23
|
- !ruby/object:Gem::Version
|
21
|
-
version: '1
|
24
|
+
version: '2.1'
|
22
25
|
type: :runtime
|
23
26
|
prerelease: false
|
24
27
|
version_requirements: !ruby/object:Gem::Requirement
|
25
28
|
requirements:
|
26
|
-
- - "
|
29
|
+
- - ">="
|
27
30
|
- !ruby/object:Gem::Version
|
28
|
-
version:
|
31
|
+
version: 1.27.0
|
32
|
+
- - "<"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.1'
|
29
35
|
- !ruby/object:Gem::Dependency
|
30
36
|
name: json
|
31
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -41,7 +47,7 @@ dependencies:
|
|
41
47
|
- !ruby/object:Gem::Version
|
42
48
|
version: '0'
|
43
49
|
- !ruby/object:Gem::Dependency
|
44
|
-
name:
|
50
|
+
name: test-unit
|
45
51
|
requirement: !ruby/object:Gem::Requirement
|
46
52
|
requirements:
|
47
53
|
- - ">="
|
@@ -68,6 +74,20 @@ dependencies:
|
|
68
74
|
- - ">="
|
69
75
|
- !ruby/object:Gem::Version
|
70
76
|
version: '0'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rake
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
type: :development
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
71
91
|
description: When your resque jobs are frequent and fast, the overhead of forking
|
72
92
|
and running your after_fork might get too big.
|
73
93
|
email:
|
@@ -83,7 +103,7 @@ files:
|
|
83
103
|
- test/helper.rb
|
84
104
|
- test/test_resque-multi-job-forks.rb
|
85
105
|
- test/test_rss_reader.rb
|
86
|
-
homepage:
|
106
|
+
homepage: https://github.com/stulentsev/resque-multi-job-forks
|
87
107
|
licenses: []
|
88
108
|
metadata: {}
|
89
109
|
post_install_message:
|
@@ -101,8 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
121
|
- !ruby/object:Gem::Version
|
102
122
|
version: '0'
|
103
123
|
requirements: []
|
104
|
-
|
105
|
-
rubygems_version: 2.4.5.1
|
124
|
+
rubygems_version: 3.1.4
|
106
125
|
signing_key:
|
107
126
|
specification_version: 4
|
108
127
|
summary: Have your resque workers process more that one job
|
@@ -110,4 +129,3 @@ test_files:
|
|
110
129
|
- test/helper.rb
|
111
130
|
- test/test_resque-multi-job-forks.rb
|
112
131
|
- test/test_rss_reader.rb
|
113
|
-
has_rdoc:
|