resque-multi-job-forks 0.5.3 → 0.5.4

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: 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