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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc14cf354d4cd292119aa6e6f06f0c59dd09faf982fe10707e69c5bbb3ef56e4
4
- data.tar.gz: 7bad129217778e76f14c1dc6a732025d5cc0bba17baaee9d81ee5a1648768edc
3
+ metadata.gz: aa7e64a4c6a3e61fd60ad02aad37062a408ad34515e0218fa4526c7c23bbb296
4
+ data.tar.gz: 540332007ba6fd7581c795f8114db0638e80390ef18c64d6336eb65ed0afbf92
5
5
  SHA512:
6
- metadata.gz: e8b5e943ec7612022b8a937c6a380b1d396be6cd2c5ebad13239961232c992dcce54d42e807c1d52f036f102defe4492f4fd498f0299c33e40e5095dc26ab48f
7
- data.tar.gz: a26e43be4a408d59d8db061c00b112e45a6fec8b6ba318e145cbac1e53b4087b12f9b2ba3510fa118714aeb8b0117673c90b6f7fb987ca028a8962c85f594e5f
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.
@@ -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], [], true)
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
@@ -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.close
89
+ @socket&.close
89
90
  @socket = nil
90
91
  end
91
92
 
@@ -200,7 +200,7 @@ module Resqued
200
200
  end
201
201
 
202
202
  if @listeners.last_good_pid == lpid
203
- @state.clear_last_good!
203
+ @listeners.clear_last_good!
204
204
  end
205
205
 
206
206
  if dead_listener = @listeners.delete(lpid)
@@ -1,3 +1,3 @@
1
1
  module Resqued
2
- VERSION = '0.10.2'
2
+ VERSION = "0.11.2".freeze
3
3
  end
@@ -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
- trap(:QUIT) { exit! 0 } # If we get a QUIT during boot, just spin back down.
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
@@ -22,7 +22,7 @@ describe "Resqued master with an extra child process" do
22
22
  }
23
23
 
24
24
  pid = spawn(env, shim_path, resqued_path, "--logfile", logfile, config_path)
25
- sleep 1.0
25
+ sleep 2.0
26
26
  pid
27
27
  end
28
28
 
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Resqued can restart" do
4
- include ResquedPath
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 20, :shuffle_queues => true
129
- queue 'a', :count => 10
130
- queue 'b', :count => 15
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(20) }
133
- it { (0..9).each { |i| expect(result[i][:queues].sort).to eq(["a", "b"]) } }
134
- it { (10..14).each { |i| expect(result[i][:queues]).to eq(["b"]) } }
135
- it { (15..19).each { |i| expect(result[i][:queues]).to eq(["*"]) } }
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(10).map { |x| x[:queues] }
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
@@ -1,5 +1,7 @@
1
1
  require "support/custom_matchers"
2
2
  require "support/resqued_path"
3
+ require "support/resqued_integration_helpers"
4
+ require "fileutils"
3
5
 
4
6
  SPEC_TEMPDIR = File.expand_path("../tmp/spec", File.dirname(__FILE__))
5
7
  FileUtils.mkpath(SPEC_TEMPDIR)
@@ -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.10.2
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: 2020-09-30 00:00:00.000000000 Z
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.0.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