sidekiq-worker-killer 0.4.0 → 0.5.0

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
  SHA1:
3
- metadata.gz: c2b88a4d00042d82a27ebd81fa27832f01873618
4
- data.tar.gz: 010d2676048b457204d403509774c4e013cd39d4
3
+ metadata.gz: bfc7e3a75eba6f95fd48ee2c0fa604cddad8328f
4
+ data.tar.gz: 367eb4d8380b612dad3300829962cdcad40509fd
5
5
  SHA512:
6
- metadata.gz: 9aef7ae408f33ed04a2cbe81ba673887d877762c803482da841a25c0878b2c91e96e6eb8b4eabfddcbcfb42b8bf7ce56e218463df867af44fadad7afb4a6a0c9
7
- data.tar.gz: 4c9cfa47bdb45445f6647ca0297e3118f4f37cc675759a3e292a96e701577c385c6f7bcce832cd8c5082f59acce4449aefad7e92160e59f8049eefa5499d95c7
6
+ metadata.gz: e26eae8384c0a43e2f57b792f094abb12b419ef58a47cfda9d2e42285ebfacf4ade437148cd20e742c5a6aaea9c1dc392e5272749aff2c1ad607e860325724a1
7
+ data.tar.gz: c347ad5878953ff5383508f0871d1beb12c1442970b2c2f6b4ff8b86a869002f75b928221506c176b395cf69b2419376e002340d70ecdfe82fb33f25c90c2d17
data/README.md CHANGED
@@ -36,10 +36,25 @@ The following options can be overrided.
36
36
  | Option | Defaults | Description |
37
37
  | ------- | ------- | ----------- |
38
38
  | max_rss | 0 MB (disabled) | max RSS in megabytes. Above this, shutdown will be triggered. |
39
- | grace_time | 900 seconds | when shutdown is triggered, the Sidekiq process will not accept new job and wait at most 15 minutes for running jobs to finish. If Float::INFINITY specified, will wait forever |
39
+ | grace_time | 900 seconds | when shutdown is triggered, the Sidekiq process will not accept new job and wait at most 15 minutes for running jobs to finish. If Float::INFINITY specified, will wait forever. |
40
40
  | shutdown_wait | 30 seconds | when the grace time expires, still running jobs get 30 seconds to terminate. After that, kill signal is triggered. |
41
41
  | kill_signal | SIGKILL | Signal to use kill Sidekiq process if it doesn't terminate. |
42
- | gc | true | Try to run garbage collection before Sidekiq process terminate in case of max_rss exceeded |
42
+ | gc | true | Try to run garbage collection before Sidekiq process terminate in case of max_rss exceeded. |
43
+ | skip_shutdown_if | Proc.new {false} | Executes a block of code after max_rss exceeds but before requesting shutdown. |
44
+
45
+ *skip_shutdown_if* is expected to return anything other than `false` or `nil` to skip shutdown.
46
+
47
+ ```ruby
48
+ require 'sidekiq/worker_killer'
49
+
50
+ Sidekiq.configure_server do |config|
51
+ config.server_middleware do |chain|
52
+ chain.add Sidekiq::WorkerKiller, max_rss: 480, skip_shutdown_if: ->(worker, job, queue) do
53
+ worker.to_s == 'LongWorker'
54
+ end
55
+ end
56
+ end
57
+ ```
43
58
 
44
59
  ## Development
45
60
 
@@ -15,16 +15,21 @@ class Sidekiq::WorkerKiller
15
15
  @shutdown_wait = options.fetch(:shutdown_wait, 30)
16
16
  @kill_signal = options.fetch(:kill_signal, "SIGKILL")
17
17
  @gc = options.fetch(:gc, true)
18
+ @skip_shutdown = options.fetch(:skip_shutdown_if, Proc.new { false })
18
19
  end
19
20
 
20
- def call(_worker, _job, _queue)
21
+ def call(worker, job, queue)
21
22
  yield
22
23
  # Skip if the max RSS is not exceeded
23
24
  return unless @max_rss > 0
24
25
  return unless current_rss > @max_rss
25
26
  GC.start(full_mark: true, immediate_sweep: true) if @gc
26
27
  return unless current_rss > @max_rss
27
- # Launch the shutdown process
28
+ if @skip_shutdown.respond_to?(:call) && @skip_shutdown.call(worker, job, queue)
29
+ warn "current RSS #{current_rss} exceeds maximum RSS #{@max_rss}, however shutdown will be ignored"
30
+ return
31
+ end
32
+
28
33
  warn "current RSS #{current_rss} of #{identity} exceeds " \
29
34
  "maximum RSS #{@max_rss}"
30
35
  request_shutdown
@@ -45,6 +50,8 @@ class Sidekiq::WorkerKiller
45
50
  warn "sending #{quiet_signal} to #{identity}"
46
51
  signal(quiet_signal, pid)
47
52
 
53
+ sleep(5) # gives Sidekiq API 5 seconds to update ProcessSet
54
+
48
55
  warn "shutting down #{identity} in #{@grace_time} seconds"
49
56
  wait_job_finish_in_grace_time
50
57
 
@@ -1,7 +1,7 @@
1
1
  # rubocop:disable Style/ClassAndModuleChildren
2
2
  module Sidekiq
3
3
  class WorkerKiller
4
- VERSION = "0.4.0".freeze
4
+ VERSION = "0.5.0".freeze
5
5
  end
6
6
  end
7
7
  # rubocop:enable Style/ClassAndModuleChildren
@@ -4,6 +4,7 @@ describe Sidekiq::WorkerKiller do
4
4
 
5
5
  before do
6
6
  allow(subject).to receive(:warn) # silence "warn" logs
7
+ allow(subject).to receive(:sleep) # reduces tests running time
7
8
  end
8
9
 
9
10
  describe "#call" do
@@ -29,6 +30,43 @@ describe Sidekiq::WorkerKiller do
29
30
  expect(GC).to receive(:start).with(full_mark: true, immediate_sweep: true)
30
31
  subject.call(worker, job, queue){}
31
32
  end
33
+
34
+ context "and skip_shutdown_if is given" do
35
+ subject{ described_class.new(max_rss: 2, skip_shutdown_if: skip_shutdown_proc) }
36
+
37
+ context "and skip_shutdown_if is a proc" do
38
+ let(:skip_shutdown_proc) { proc { |worker| true } }
39
+ it "should NOT request shutdown" do
40
+ expect(subject).not_to receive(:request_shutdown)
41
+ subject.call(worker, job, queue){}
42
+ end
43
+ end
44
+
45
+ context "and skip_shutdown_if is a lambda" do
46
+ let(:skip_shutdown_proc) { ->(worker, job, queue) { true } }
47
+ it "should NOT request shutdown" do
48
+ expect(subject).not_to receive(:request_shutdown)
49
+ subject.call(worker, job, queue){}
50
+ end
51
+ end
52
+
53
+ context "and skip_shutdown_if returns false" do
54
+ let(:skip_shutdown_proc) { proc { |worker, job, queue| false } }
55
+ it "should still request shutdown" do
56
+ expect(subject).to receive(:request_shutdown)
57
+ subject.call(worker, job, queue){}
58
+ end
59
+ end
60
+
61
+ context "and skip_shutdown_if returns nil" do
62
+ let(:skip_shutdown_proc) { proc { |worker, job, queue| nil } }
63
+ it "should still request shutdown" do
64
+ expect(subject).to receive(:request_shutdown)
65
+ subject.call(worker, job, queue){}
66
+ end
67
+ end
68
+ end
69
+
32
70
  context "when gc is false" do
33
71
  subject{ described_class.new(max_rss: 2, gc: false) }
34
72
  it "should not call garbage collect" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-worker-killer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyrille Courtiere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-26 00:00:00.000000000 Z
11
+ date: 2019-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: get_process_mem