resque-multi-job-forks 0.5.3 → 0.5.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cb28f2bcae133394c2e1a4e2cd71c256030fdefcb86dfb9c3300913056a9324
4
- data.tar.gz: a2a002cc266e7c42ac9e92388ea2837392e697b3a27aa4d033577223f3900596
3
+ metadata.gz: 142ac780146f82b8ab449daa58bfcb1319f113207045b9c94d6d81595e9dd399
4
+ data.tar.gz: fcaf1e33dc1aefae61e4a44f1cbab884635d266f9dbaed0fdcc8c9e458a0b720
5
5
  SHA512:
6
- metadata.gz: a66af847f0dece95ba2e0990433d5dfde52cee08b51b9163f3551269d5c8fd0bc31c2207a45aad23a3d1af19e065482c5871afd4f7014bcd58f10d2b24dae9db
7
- data.tar.gz: 5acdcd7e2b3eb9ee375852a6d3539016994e0344a57b1256e33bacaf533fce2fb89c088f3fb7dfb2b96002e10bd8930c9161b9591b17cafced036eb8ae13ae75
6
+ metadata.gz: ef14ecd365691be385e6378b42beb60bd712687bcd1907e8899b5bb7e3b13b0c1c1a8821570631d7accb047cafeff444210fff7ea72802c036cc3b1d79c1976d
7
+ data.tar.gz: bf62253ac1e9cc96e6efc3c9d83da3918b479dc4ea904dfc3e0e47a860641cd507376a878c85c6982c9115942e80423a2351d25bebc10800ce904272d06f7520
@@ -10,6 +10,8 @@ module Resque
10
10
  attr_accessor :memory_threshold
11
11
  attr_reader :jobs_processed
12
12
 
13
+ WorkerTerminated = Class.new(StandardError)
14
+
13
15
  def self.multi_jobs_per_fork?
14
16
  ENV["DISABLE_MULTI_JOBS_PER_FORK"].nil?
15
17
  end
@@ -22,6 +24,20 @@ module Resque
22
24
  else
23
25
  if term_child
24
26
  unregister_signal_handlers
27
+ trap('TERM') do
28
+ trap('TERM') do
29
+ # Ignore subsequent term signals
30
+ end
31
+
32
+ if @performing_job
33
+ # If a job is in progress, stop it immediately.
34
+ raise TermException.new("SIGTERM")
35
+ else
36
+ # If we're not currently running a job, shut down cleanly.
37
+ # This allows us to push unworked jobs back on the queue.
38
+ shutdown
39
+ end
40
+ end
25
41
  trap('QUIT') { shutdown }
26
42
  end
27
43
  raise NotImplementedError, "Pretending to not have forked"
@@ -39,9 +55,20 @@ module Resque
39
55
 
40
56
  def perform_with_multi_job_forks(job = nil)
41
57
  @fork_per_job = true unless fork_hijacked? # reconnect and after_fork
58
+ if shutdown?
59
+ # We got a request to shut down _after_ grabbing a job but _before_ starting work
60
+ # on it. Immediately report the job as failed and return.
61
+ if job
62
+ report_failed_job(job, WorkerTerminated.new("shutdown before job start"))
63
+ end
64
+ return
65
+ end
66
+ @performing_job = true
42
67
  perform_without_multi_job_forks(job)
43
68
  hijack_fork unless fork_hijacked?
44
69
  @jobs_processed += 1
70
+ ensure
71
+ @performing_job = false
45
72
  end
46
73
  alias_method :perform_without_multi_job_forks, :perform
47
74
  alias_method :perform, :perform_with_multi_job_forks
data/test/helper.rb CHANGED
@@ -19,6 +19,7 @@ Resque.redis = $redis
19
19
  # set `VERBOSE=true` when running the tests to view resques log output.
20
20
  module Resque
21
21
  class Worker
22
+ attr_accessor :start_lag
22
23
 
23
24
  def log_with_severity(severity, msg)
24
25
  if ENV['VERBOSE']
@@ -27,6 +28,18 @@ module Resque
27
28
  end
28
29
  end
29
30
 
31
+ def report_failed_job(job, exception)
32
+ $SEQ_WRITER.print "failed_job_#{exception.class.name.downcase.gsub('::', '_')}\n"
33
+ end
34
+
35
+ def fork_hijacked?
36
+ if @release_fork_limit
37
+ if start_lag
38
+ sleep start_lag
39
+ end
40
+ end
41
+ @release_fork_limit
42
+ end
30
43
  end
31
44
  end
32
45
 
@@ -91,11 +91,35 @@ class TestResqueMultiJobForks < Test::Unit::TestCase
91
91
  sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
92
92
 
93
93
  # test the sequence is correct.
94
- assert_equal([:before_fork, :after_fork,
94
+ assert_equal([:before_fork, :after_fork, :failed_job_resque_termexception,
95
95
  :before_child_exit_1], sequence, 'correct sequence')
96
96
  t.join
97
97
  end
98
98
 
99
+ def test_shutdown_between_jobs
100
+ @worker.log_with_severity :debug, "in test_sigterm_shutdown_during_first_job"
101
+ # enough time for all jobs to process.
102
+ @worker.seconds_per_fork = 60
103
+ @worker.term_child = true
104
+ @worker.graceful_term = true
105
+ @worker.term_timeout = 0.5
106
+ @worker.start_lag = 1
107
+
108
+ Resque.enqueue(QuickSequenceJob, 1)
109
+ Resque.enqueue(SequenceJob, 2)
110
+ t = Thread.new do
111
+ sleep 2
112
+ Process.kill("TERM", @worker.pid)
113
+ end
114
+ @worker.work(0)
115
+ $SEQ_WRITER.close
116
+
117
+ sequence = $SEQ_READER.each_line.map {|l| l.strip.to_sym }
118
+ assert_equal([:before_fork, :after_fork, :work_1, :before_child_exit_1, :failed_job_resque_worker_workerterminated], sequence, 'correct sequence')
119
+
120
+ t.join
121
+ end
122
+
99
123
  # test we can also limit fork job process by a job limit.
100
124
  def test_job_limit_sequence_of_events
101
125
  @worker.log_with_severity :debug, "in test_job_limit_sequence_of_events"
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.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mick Staugaard
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-08-17 00:00:00.000000000 Z
13
+ date: 2021-11-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: resque
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
- rubygems_version: 3.1.4
124
+ rubygems_version: 3.1.6
125
125
  signing_key:
126
126
  specification_version: 4
127
127
  summary: Have your resque workers process more that one job