sucker_punch 2.0.2 → 2.0.3

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
  SHA1:
3
- metadata.gz: ed0c4d4c1a73adb49bc0978312f0f82b58cf375f
4
- data.tar.gz: 8ba1cc2b966c1862ea88d84372f65fe78a5b97d4
3
+ metadata.gz: f9888e735e4566c4c0d789d328c78553caa09e35
4
+ data.tar.gz: 5e70f216542d0bc65fb5fbb1757dfce2ce529100
5
5
  SHA512:
6
- metadata.gz: 6ae1cbb00a767473ac432b7a16fea5af8d507f2cd5ae3a15ada78a2ee18469fd48279acf82133c85a536958d1218af3c9a276e062a06140520385e8d69deda14
7
- data.tar.gz: d854f9292c2d629f711736c04a0fd33e9220991f4f07901548c663d60eb757687a2fc3ef013cf4b7ee3e73240ff90522aea787ec6305c0ccbfb4c28518f7122d
6
+ metadata.gz: 295aceab156ca6df316d095be72b2052591a0a4895893ce75e4751db160b8eb675dac3385757c94f0776b90587c292bcf4a1b666df6a3c387d471a4569e1c520
7
+ data.tar.gz: 49db7fbff4f68c9015566162ba26794365d535a5dfc0a9957dc107e4006ec7baae125ad52c1b0ff29c813f080aaf1919c0b2b0bec4e8ac6498adda43fa254d18
data/.travis.yml CHANGED
@@ -4,7 +4,8 @@ rvm:
4
4
  - 2.0.0
5
5
  - 2.1.8
6
6
  - 2.2.4
7
- - 2.3.0
7
+ - 2.3.4
8
+ - 2.4.1
8
9
  - ruby-head
9
10
 
10
11
  matrix:
data/CHANGES.md CHANGED
@@ -1,3 +1,8 @@
1
+ 2.0.3
2
+ -------
3
+ - Rewrite shutdown strategy to fix bug related to premature shutdown when only
4
+ 1 job is in enqueued when a job has more than 1 worker
5
+
1
6
  2.0.2
2
7
  -------
3
8
  - Don't consider global shutdown bool when exhausting the queue during
data/README.md CHANGED
@@ -14,8 +14,7 @@ crunching, or social platform manipulation. No reason to hold up a
14
14
  user when you can do these things in the background within the same
15
15
  process as your web application...
16
16
 
17
- Sucker Punch is built on top of [concurrent-ruby]
18
- (https://github.com/ruby-concurrency/concurrent-ruby). Each job is setup as
17
+ Sucker Punch is built on top of [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby). Each job is setup as
19
18
  a pool, which equates to its own queue with individual workers working against
20
19
  the jobs. Unlike most other background processing libraries, Sucker
21
20
  Punch's jobs are stored in memory. The benefit to this is there is no
@@ -270,11 +269,11 @@ gem 'sucker_punch'
270
269
  And then configure the backend to use Sucker Punch:
271
270
 
272
271
  ```Ruby
273
- # config/initializers/sucker_punch.rb
274
- Rails.application.configure do
272
+ # config/application.rb
273
+ class Application < Rails::Application
274
+ # ...
275
275
  config.active_job.queue_adapter = :sucker_punch
276
276
  end
277
-
278
277
  ```
279
278
 
280
279
  If you want to use Sucker Punch version `2.0.0+` with Rails `< 5.0.0`, be sure
@@ -1,6 +1,6 @@
1
- class <%= class_name %>Job
1
+ class <%= class_name %>Job
2
2
  include SuckerPunch::Job
3
-
3
+
4
4
  def perform
5
5
  raise NotImplementedError
6
6
  end
@@ -66,21 +66,43 @@ module SuckerPunch
66
66
  queues
67
67
  end
68
68
 
69
+ PAUSE_TIME = STDOUT.tty? ? 0.1 : 0.5
70
+
69
71
  def self.shutdown_all
72
+ deadline = Time.now + SuckerPunch.shutdown_timeout
73
+
70
74
  if SuckerPunch::RUNNING.make_false
75
+ # If a job is enqueued right before the script exits
76
+ # (command line, rake task, etc.), the system needs an
77
+ # interval to allow the enqueue jobs to make it in to the system
78
+ # otherwise the queue will look idle
79
+ sleep PAUSE_TIME
71
80
 
72
81
  queues = all
73
- latch = Concurrent::CountDownLatch.new(queues.length)
74
82
 
75
- queues.each do |queue|
76
- queue.post(latch) { |l| l.count_down }
77
- queue.shutdown
78
- end
83
+ # Issue shutdown to each queue and let them wrap up their work. This
84
+ # prevents new jobs from being enqueued and lets the pool clean up
85
+ # after itself
86
+ queues.each { |queue| queue.shutdown }
87
+
88
+ # return if every queue is empty and workers in every queue are idle
89
+ return if queues.all? { |queue| queue.idle? }
90
+
91
+ SuckerPunch.logger.info("Pausing to allow workers to finish...")
79
92
 
80
- unless latch.wait(SuckerPunch.shutdown_timeout)
81
- queues.each { |queue| queue.kill }
82
- SuckerPunch.logger.info("Queued jobs didn't finish before shutdown_timeout...killing remaining jobs")
93
+ remaining = deadline - Time.now
94
+
95
+ # Continue to loop through each queue and test if it's idle, while
96
+ # respecting the shutdown timeout
97
+ while remaining > PAUSE_TIME
98
+ return if queues.all? { |queue| queue.idle? }
99
+ sleep PAUSE_TIME
100
+ remaining = deadline - Time.now
83
101
  end
102
+
103
+ # Queues haven't finished work. Aggressively kill them.
104
+ SuckerPunch.logger.warn("Queued jobs didn't finish before shutdown_timeout...killing remaining jobs")
105
+ queues.each { |queue| queue.kill }
84
106
  end
85
107
  end
86
108
 
@@ -115,6 +137,10 @@ module SuckerPunch
115
137
  synchronize { @running }
116
138
  end
117
139
 
140
+ def idle?
141
+ enqueued_jobs == 0 && busy_workers == 0
142
+ end
143
+
118
144
  def ==(other)
119
145
  pool == other.pool
120
146
  end
@@ -146,15 +172,12 @@ module SuckerPunch
146
172
  end
147
173
 
148
174
  def kill
149
- if can_initiate_shutdown?
150
- @pool.kill
151
- end
175
+ @pool.kill
152
176
  end
153
177
 
154
178
  def shutdown
155
- if can_initiate_shutdown?
156
- @pool.shutdown
157
- end
179
+ synchronize { @running = false }
180
+ @pool.shutdown
158
181
  end
159
182
 
160
183
  protected
@@ -162,19 +185,6 @@ module SuckerPunch
162
185
  def pool
163
186
  @pool
164
187
  end
165
-
166
- private
167
-
168
- def can_initiate_shutdown?
169
- synchronize do
170
- if @running
171
- @running = false
172
- true
173
- else
174
- false
175
- end
176
- end
177
- end
178
188
  end
179
189
  end
180
190
 
@@ -1,3 +1,3 @@
1
1
  module SuckerPunch
2
- VERSION = "2.0.2"
2
+ VERSION = "2.0.3"
3
3
  end
data/sucker_punch.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
9
9
  gem.authors = ["Brandon Hilkert"]
10
10
  gem.email = ["brandonhilkert@gmail.com"]
11
11
  gem.description = %q{Asynchronous processing library for Ruby}
12
- gem.summary = %q{Sucker Punch is a Ruby asynchronous processing using Celluloid, heavily influenced by Sidekiq and girl_friday.}
12
+ gem.summary = %q{Sucker Punch is a Ruby asynchronous processing using concurrent-ruby, heavily influenced by Sidekiq and girl_friday.}
13
13
  gem.homepage = "https://github.com/brandonhilkert/sucker_punch"
14
14
  gem.license = "MIT"
15
15
 
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
20
 
21
- gem.post_install_message = "Sucker Punch v2.0 introduces backwards-incompatible changes.\nPlease see https://github.com/brandonhilkert/sucker_punch/blob/master/CHANGES.md#20 for details."
21
+ gem.post_install_message = "Sucker Punch v2.0 introduces backwards-incompatible changes.\nPlease see https://github.com/brandonhilkert/sucker_punch/blob/master/CHANGES.md#200 for details."
22
22
 
23
23
  gem.add_development_dependency "rake", "~> 10.0"
24
24
  gem.add_development_dependency "minitest"
@@ -82,33 +82,29 @@ module SuckerPunch
82
82
  assert_equal true, queue.running?
83
83
  end
84
84
 
85
- def test_jobs_can_be_posted_to_pool
86
- arr = []
87
- fake_pool = FakePool.new
88
- queue = SuckerPunch::Queue.new "fake", fake_pool
89
- queue.post(1, 2) { |args| arr.push args }
90
- assert_equal [1, 2], arr.first
85
+ def test_idle_considers_queue_workers_and_length
86
+ queue = SuckerPunch::Queue.find_or_create(FakeNilJob.to_s)
87
+ assert_equal true, queue.idle?
91
88
  end
92
89
 
93
- def test_jobs_arent_posted_if_queue_isnt_running
90
+ def test_jobs_can_be_posted_to_pool
94
91
  arr = []
95
92
  fake_pool = FakePool.new
96
- queue = SuckerPunch::Queue.new "fake", fake_pool
97
- queue.kill
93
+ queue = SuckerPunch::Queue.new "fake", fake_pool
98
94
  queue.post(1, 2) { |args| arr.push args }
99
- assert arr.empty?
95
+ assert_equal [1, 2], arr.first
100
96
  end
101
97
 
102
98
  def test_kill_sends_kill_to_pool
103
99
  fake_pool = FakePool.new
104
- queue = SuckerPunch::Queue.new "fake", fake_pool
100
+ queue = SuckerPunch::Queue.new "fake", fake_pool
105
101
  queue.kill
106
102
  assert_equal :kill, fake_pool.signals.first
107
103
  end
108
104
 
109
105
  def test_shutdown_sends_shutdown_to_pool
110
106
  fake_pool = FakePool.new
111
- queue = SuckerPunch::Queue.new "fake", fake_pool
107
+ queue = SuckerPunch::Queue.new "fake", fake_pool
112
108
  queue.shutdown
113
109
  assert_equal :shutdown, fake_pool.signals.first
114
110
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sucker_punch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Hilkert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-25 00:00:00.000000000 Z
11
+ date: 2017-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -104,7 +104,7 @@ licenses:
104
104
  metadata: {}
105
105
  post_install_message: |-
106
106
  Sucker Punch v2.0 introduces backwards-incompatible changes.
107
- Please see https://github.com/brandonhilkert/sucker_punch/blob/master/CHANGES.md#20 for details.
107
+ Please see https://github.com/brandonhilkert/sucker_punch/blob/master/CHANGES.md#200 for details.
108
108
  rdoc_options: []
109
109
  require_paths:
110
110
  - lib
@@ -120,11 +120,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  version: '0'
121
121
  requirements: []
122
122
  rubyforge_project:
123
- rubygems_version: 2.5.1
123
+ rubygems_version: 2.6.11
124
124
  signing_key:
125
125
  specification_version: 4
126
- summary: Sucker Punch is a Ruby asynchronous processing using Celluloid, heavily influenced
127
- by Sidekiq and girl_friday.
126
+ summary: Sucker Punch is a Ruby asynchronous processing using concurrent-ruby, heavily
127
+ influenced by Sidekiq and girl_friday.
128
128
  test_files:
129
129
  - test/sucker_punch/async_syntax_test.rb
130
130
  - test/sucker_punch/counter_test.rb