resqued 0.10.2 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +17 -0
- data/docs/signals.md +4 -0
- data/lib/resqued/exec_on_hup.rb +1 -1
- data/lib/resqued/listener.rb +3 -2
- data/lib/resqued/master.rb +1 -1
- data/lib/resqued/version.rb +1 -1
- data/lib/resqued/worker.rb +5 -1
- data/spec/integration/listener_still_starting_spec.rb +24 -0
- data/spec/integration/master_inherits_child_spec.rb +1 -1
- data/spec/integration/restart_spec.rb +1 -43
- data/spec/resqued/config/worker_spec.rb +8 -8
- data/spec/spec_helper.rb +2 -0
- data/spec/support/resqued_integration_helpers.rb +50 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa7e64a4c6a3e61fd60ad02aad37062a408ad34515e0218fa4526c7c23bbb296
|
4
|
+
data.tar.gz: 540332007ba6fd7581c795f8114db0638e80390ef18c64d6336eb65ed0afbf92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 402d4c507e5809832e8e05ff3f0e3e243fdb8c3a9378d84e6589147b649b80426b5a934644e10cebc9d467948073e0db8f3771f803ac4befb80d4176233050dc
|
7
|
+
data.tar.gz: 9a51246b791079456dd26faafa988aa9e2994c76bcd7a554b6a4f1c45539d2921604e17ee7be389b089cfd77cbeab60094f1da03c5ef85a19e9fa9de6acd32f9
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
Starting with version 0.6.1, resqued uses semantic versioning to indicate incompatibilities between the master process, listener process, and configuration.
|
2
2
|
|
3
|
+
v0.11.2
|
4
|
+
-------
|
5
|
+
* Add compatibility with Ruby 3.1. (#63)
|
6
|
+
* Switch to GitHub Actions for CI. (#64)
|
7
|
+
|
8
|
+
v0.11.1
|
9
|
+
-------
|
10
|
+
* Fix a crash during shutdown. (#62)
|
11
|
+
|
12
|
+
v0.11.0
|
13
|
+
-------
|
14
|
+
* Ignore SIGHUP in Listener and Worker processes. (#61)
|
15
|
+
|
16
|
+
v0.10.3
|
17
|
+
-------
|
18
|
+
* Fix a timing related crash during reload. (#60)
|
19
|
+
|
3
20
|
v0.10.2
|
4
21
|
-------
|
5
22
|
* Shut down cleanly even if there are other stray child processes of the master. (#59)
|
data/docs/signals.md
CHANGED
@@ -34,6 +34,8 @@ The Listener process forwards `SIGCONT` to all of its workers.
|
|
34
34
|
|
35
35
|
The Listener process handles `SIGINT`, `SIGTERM`, and `SIGQUIT`. When it receives one of these signals, it goes into shutdown mode. It sends the received signal to all of its workers. When all workers have exited, the Listener process exits.
|
36
36
|
|
37
|
+
The Listener process handles `SIGHUP` and does nothing. This makes it easier to reload resqued in a docker container, since many container platforms will send a requested signal to all processes in the container.
|
38
|
+
|
37
39
|
## Worker
|
38
40
|
|
39
41
|
The Worker process uses resque's signal handling. Resque 1.23.0 handles the following signals:
|
@@ -44,3 +46,5 @@ The Worker process uses resque's signal handling. Resque 1.23.0 handles the foll
|
|
44
46
|
* `USR1`: Kill the forked child immediately, continue processing jobs.
|
45
47
|
* `USR2`: Don't process any new jobs
|
46
48
|
* `CONT`: Start processing jobs again after a USR2
|
49
|
+
|
50
|
+
Resqued leaves a handler for `HUP` in place that does nothing. This makes it easier to reload resqued in a docker container, since many container platforms will send a requested signal to all processes in the container.
|
data/lib/resqued/exec_on_hup.rb
CHANGED
@@ -34,7 +34,7 @@ module Resqued
|
|
34
34
|
|
35
35
|
# Internal: Restore the master's state, and remove the state file.
|
36
36
|
def self.restore_state(state, path)
|
37
|
-
data = YAML.safe_load(File.read(path), [Symbol],
|
37
|
+
data = YAML.safe_load(File.read(path), permitted_classes: [Symbol], aliases: true)
|
38
38
|
Resqued::START_CTX.replace(data[:start_ctx] || {})
|
39
39
|
state.restore(data[:state])
|
40
40
|
File.unlink(path) rescue nil
|
data/lib/resqued/listener.rb
CHANGED
@@ -63,12 +63,13 @@ module Resqued
|
|
63
63
|
end
|
64
64
|
|
65
65
|
SIGNALS = [:CONT, :QUIT, :INT, :TERM].freeze
|
66
|
-
ALL_SIGNALS = SIGNALS + [:CHLD]
|
66
|
+
ALL_SIGNALS = SIGNALS + [:CHLD, :HUP]
|
67
67
|
|
68
68
|
SIGNAL_QUEUE = [] # rubocop: disable Style/MutableConstant
|
69
69
|
|
70
70
|
# Public: Run the main loop.
|
71
71
|
def run
|
72
|
+
trap(:HUP) {} # ignore this, in case it trickles in from the master.
|
72
73
|
trap(:CHLD) { awake }
|
73
74
|
SIGNALS.each { |signal| trap(signal) { SIGNAL_QUEUE << signal; awake } }
|
74
75
|
@socket.close_on_exec = true
|
@@ -85,7 +86,7 @@ module Resqued
|
|
85
86
|
|
86
87
|
write_procline("shutdown")
|
87
88
|
burn_down_workers(exit_signal || :QUIT)
|
88
|
-
@socket
|
89
|
+
@socket&.close
|
89
90
|
@socket = nil
|
90
91
|
end
|
91
92
|
|
data/lib/resqued/master.rb
CHANGED
data/lib/resqued/version.rb
CHANGED
data/lib/resqued/worker.rb
CHANGED
@@ -91,7 +91,11 @@ module Resqued
|
|
91
91
|
else
|
92
92
|
# In case we get a signal before resque is ready for it.
|
93
93
|
Resqued::Listener::ALL_SIGNALS.each { |signal| trap(signal, "DEFAULT") }
|
94
|
-
|
94
|
+
# Continue ignoring SIGHUP, though.
|
95
|
+
trap(:HUP) {}
|
96
|
+
# If we get a QUIT during boot, just spin back down.
|
97
|
+
trap(:QUIT) { exit! 0 }
|
98
|
+
|
95
99
|
$0 = "STARTING RESQUE FOR #{queues.join(',')}"
|
96
100
|
resque_worker = @worker_factory.call(queues)
|
97
101
|
@config.after_fork(resque_worker)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Listener still starting on SIGHUP" do
|
4
|
+
include ResquedIntegrationHelpers
|
5
|
+
|
6
|
+
it "expect master not to crash" do
|
7
|
+
start_resqued config: <<-CONFIG
|
8
|
+
before_fork do
|
9
|
+
sleep 1
|
10
|
+
end
|
11
|
+
CONFIG
|
12
|
+
expect_running listener: "listener #1"
|
13
|
+
restart_resqued
|
14
|
+
sleep 2
|
15
|
+
expect_running listener: "listener #2"
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
begin
|
20
|
+
Process.kill(:QUIT, @pid) if @pid
|
21
|
+
rescue Errno::ESRCH
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Resqued can restart" do
|
4
|
-
include
|
4
|
+
include ResquedIntegrationHelpers
|
5
5
|
|
6
6
|
it "expect to be able to restart" do
|
7
7
|
start_resqued
|
@@ -18,46 +18,4 @@ describe "Resqued can restart" do
|
|
18
18
|
rescue Errno::ESRCH
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
def expect_running(listener:)
|
23
|
-
processes = list_processes
|
24
|
-
expect(processes).to include(is_resqued_master)
|
25
|
-
listeners = processes.select { |p| p[:ppid] == @pid }.map { |p| p[:args] }
|
26
|
-
expect(listeners).to all(match(/#{listener}/)).and(satisfy { |l| l.size == 1 })
|
27
|
-
end
|
28
|
-
|
29
|
-
def expect_not_running
|
30
|
-
processes = list_processes
|
31
|
-
expect(processes).not_to include(is_resqued_master)
|
32
|
-
end
|
33
|
-
|
34
|
-
def start_resqued
|
35
|
-
# Don't configure any workers. That way, we don't need to have redis running.
|
36
|
-
config_path = File.join(SPEC_TEMPDIR, "config.rb")
|
37
|
-
File.write(config_path, "")
|
38
|
-
|
39
|
-
logfile = File.join(SPEC_TEMPDIR, "resqued.log")
|
40
|
-
File.write(logfile, "") # truncate it
|
41
|
-
|
42
|
-
@pid = spawn resqued_path, "--logfile", logfile, config_path
|
43
|
-
sleep 1.0
|
44
|
-
end
|
45
|
-
|
46
|
-
def restart_resqued
|
47
|
-
Process.kill(:HUP, @pid)
|
48
|
-
sleep 1.0
|
49
|
-
end
|
50
|
-
|
51
|
-
def stop_resqued
|
52
|
-
Process.kill(:TERM, @pid)
|
53
|
-
sleep 1.0
|
54
|
-
end
|
55
|
-
|
56
|
-
def list_processes
|
57
|
-
`ps axo pid,ppid,args`.lines.map { |line| pid, ppid, args = line.strip.split(/\s+/, 3); { pid: pid.to_i, ppid: ppid.to_i, args: args } }
|
58
|
-
end
|
59
|
-
|
60
|
-
def is_resqued_master
|
61
|
-
satisfy { |p| p[:pid] == @pid && p[:args] =~ /resqued-/ }
|
62
|
-
end
|
63
21
|
end
|
@@ -125,17 +125,17 @@ describe Resqued::Config::Worker do
|
|
125
125
|
|
126
126
|
context "pool, with shuffled queues" do
|
127
127
|
let(:config) { <<-END_CONFIG }
|
128
|
-
worker_pool
|
129
|
-
queue 'a', :count =>
|
130
|
-
queue 'b', :count =>
|
128
|
+
worker_pool 200, :shuffle_queues => true
|
129
|
+
queue 'a', :count => 100
|
130
|
+
queue 'b', :count => 150
|
131
131
|
END_CONFIG
|
132
|
-
it { expect(result.size).to eq(
|
133
|
-
it { (0..
|
134
|
-
it { (
|
135
|
-
it { (
|
132
|
+
it { expect(result.size).to eq(200) }
|
133
|
+
it { (0..99).each { |i| expect(result[i][:queues].sort).to eq(["a", "b"]) } }
|
134
|
+
it { (100..149).each { |i| expect(result[i][:queues]).to eq(["b"]) } }
|
135
|
+
it { (150..199).each { |i| expect(result[i][:queues]).to eq(["*"]) } }
|
136
136
|
it { result.each { |x| expect(x).not_to have_key(:shuffle_queues) } }
|
137
137
|
it do
|
138
|
-
shuffled_queues = result.take(
|
138
|
+
shuffled_queues = result.take(100).map { |x| x[:queues] }
|
139
139
|
expect(shuffled_queues.sort.uniq).to eq([["a", "b"], ["b", "a"]]) # Some of the queues should be shuffled
|
140
140
|
end
|
141
141
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
module ResquedIntegrationHelpers
|
2
|
+
include ResquedPath
|
3
|
+
|
4
|
+
def start_resqued(config: "", debug: false)
|
5
|
+
# Don't configure any workers. That way, we don't need to have redis running.
|
6
|
+
config_path = File.join(SPEC_TEMPDIR, "config.rb")
|
7
|
+
File.write(config_path, config)
|
8
|
+
|
9
|
+
@pid =
|
10
|
+
if debug
|
11
|
+
spawn resqued_path, config_path
|
12
|
+
else
|
13
|
+
logfile = File.join(SPEC_TEMPDIR, "resqued.log")
|
14
|
+
File.write(logfile, "") # truncate it
|
15
|
+
|
16
|
+
spawn resqued_path, "--logfile", logfile, config_path
|
17
|
+
end
|
18
|
+
sleep 1.0
|
19
|
+
end
|
20
|
+
|
21
|
+
def restart_resqued
|
22
|
+
Process.kill(:HUP, @pid)
|
23
|
+
sleep 1.0
|
24
|
+
end
|
25
|
+
|
26
|
+
def expect_running(listener:)
|
27
|
+
processes = list_processes
|
28
|
+
expect(processes).to include(is_resqued_master)
|
29
|
+
listeners = processes.select { |p| p[:ppid] == @pid }.map { |p| p[:args] }
|
30
|
+
expect(listeners).to all(match(/#{listener}/)).and(satisfy { |l| l.size == 1 })
|
31
|
+
end
|
32
|
+
|
33
|
+
def expect_not_running
|
34
|
+
processes = list_processes
|
35
|
+
expect(processes).not_to include(is_resqued_master)
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop_resqued
|
39
|
+
Process.kill(:TERM, @pid)
|
40
|
+
sleep 1.0
|
41
|
+
end
|
42
|
+
|
43
|
+
def list_processes
|
44
|
+
`ps axo pid,ppid,args`.lines.map { |line| pid, ppid, args = line.strip.split(/\s+/, 3); { pid: pid.to_i, ppid: ppid.to_i, args: args } }
|
45
|
+
end
|
46
|
+
|
47
|
+
def is_resqued_master
|
48
|
+
satisfy { |p| p[:pid] == @pid && p[:args] =~ /resqued-/ }
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resqued
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Burke
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kgio
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- spec/fixtures/test_case_clean.rb
|
138
138
|
- spec/fixtures/test_case_environment.rb
|
139
139
|
- spec/fixtures/test_case_no_workers.rb
|
140
|
+
- spec/integration/listener_still_starting_spec.rb
|
140
141
|
- spec/integration/master_inherits_child_spec.rb
|
141
142
|
- spec/integration/restart_spec.rb
|
142
143
|
- spec/resqued/backoff_spec.rb
|
@@ -149,6 +150,7 @@ files:
|
|
149
150
|
- spec/spec_helper.rb
|
150
151
|
- spec/support/custom_matchers.rb
|
151
152
|
- spec/support/extra-child-shim
|
153
|
+
- spec/support/resqued_integration_helpers.rb
|
152
154
|
- spec/support/resqued_path.rb
|
153
155
|
homepage: https://github.com/spraints/resqued
|
154
156
|
licenses:
|
@@ -169,14 +171,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
171
|
- !ruby/object:Gem::Version
|
170
172
|
version: '0'
|
171
173
|
requirements: []
|
172
|
-
rubygems_version: 3.
|
174
|
+
rubygems_version: 3.1.6
|
173
175
|
signing_key:
|
174
176
|
specification_version: 4
|
175
177
|
summary: Daemon of resque workers
|
176
178
|
test_files:
|
177
179
|
- spec/spec_helper.rb
|
178
180
|
- spec/integration/restart_spec.rb
|
181
|
+
- spec/integration/listener_still_starting_spec.rb
|
179
182
|
- spec/integration/master_inherits_child_spec.rb
|
183
|
+
- spec/support/resqued_integration_helpers.rb
|
180
184
|
- spec/support/custom_matchers.rb
|
181
185
|
- spec/support/resqued_path.rb
|
182
186
|
- spec/support/extra-child-shim
|