sucker_punch 2.0.0.beta1 → 2.0.0.beta2
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 +4 -4
- data/.travis.yml +2 -14
- data/CHANGES.md +6 -0
- data/README.md +37 -0
- data/lib/sucker_punch.rb +0 -1
- data/lib/sucker_punch/queue.rb +4 -6
- data/lib/sucker_punch/version.rb +1 -1
- data/sucker_punch.gemspec +1 -1
- data/test/sucker_punch/job_test.rb +45 -22
- data/test/sucker_punch/queue_test.rb +63 -9
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 805f11babbfd83d6221c804f50749d0f37acef55
|
4
|
+
data.tar.gz: a440db16a4fb7062aea253a4aa090211f3a5aed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2649c57a07871e7fb765e43b1923d626b62ae73ea143016053dd5a5d213da49d02c6da529d475ec108ff94233fb6694d522e71c68d99004c6bc934dfe4610166
|
7
|
+
data.tar.gz: b313fa9e6681e2f0839fab9da0f1bbb1b7bf1b51bb9897df49157235881656de697471349652f93ce71584578b66b242566d4372b31d41637a7ba9ac680f5a4b
|
data/.travis.yml
CHANGED
@@ -2,23 +2,11 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- rbx-2
|
4
4
|
- 2.0.0
|
5
|
-
- 2.1.
|
6
|
-
- 2.2.
|
5
|
+
- 2.1.8
|
6
|
+
- 2.2.4
|
7
7
|
- 2.3.0
|
8
8
|
- ruby-head
|
9
|
-
- jruby-9.0.1.0
|
10
|
-
- jruby-9.0.3.0
|
11
|
-
- jruby-9.0.4.0
|
12
|
-
- jruby-head
|
13
|
-
|
14
|
-
jdk:
|
15
|
-
- oraclejdk8
|
16
9
|
|
17
10
|
matrix:
|
18
11
|
allow_failures:
|
19
12
|
- rvm: rbx-2
|
20
|
-
- rvm: jruby-head
|
21
|
-
|
22
|
-
before_script:
|
23
|
-
- "echo $JAVA_OPTS"
|
24
|
-
- "export JAVA_OPTS=-Xmx1024m"
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -41,6 +41,33 @@ Or install it yourself as:
|
|
41
41
|
|
42
42
|
$ gem install sucker_punch
|
43
43
|
|
44
|
+
## Backwards Compatibility
|
45
|
+
|
46
|
+
In version `~> 2.0.0`, the syntax to enqueue an asynchronous background job has changed from:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
LogJob.new.async.perform(...)
|
50
|
+
```
|
51
|
+
|
52
|
+
to:
|
53
|
+
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
LogJob.perform_async(...)
|
57
|
+
```
|
58
|
+
|
59
|
+
If you're upgrading from a pre-`2.0.0` release and want to retain the old
|
60
|
+
syntax `LogJob.new.async.perform(...)`, you can include
|
61
|
+
`sucker_punch/async_syntax` in your application.
|
62
|
+
|
63
|
+
For Rails, you could add an initializer:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
# config/initializers/sucker_punch.rb
|
67
|
+
|
68
|
+
require 'sucker_punch/async_syntax'
|
69
|
+
```
|
70
|
+
|
44
71
|
## Usage
|
45
72
|
|
46
73
|
Each job acts as its own queue and should be a separate Ruby class that:
|
@@ -252,6 +279,16 @@ end
|
|
252
279
|
|
253
280
|
```
|
254
281
|
|
282
|
+
If you want to use Sucker Punch version `2.0.0+` with Rails `< 5.0.0`, be sure
|
283
|
+
to include the backwards compatibility module in an initializer:
|
284
|
+
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
# config/initializers/sucker_punch.rb
|
288
|
+
|
289
|
+
require 'sucker_punch/async_syntax'
|
290
|
+
```
|
291
|
+
|
255
292
|
## Troubleshooting
|
256
293
|
|
257
294
|
### Initializers for forking servers (Unicorn, Passenger, etc.)
|
data/lib/sucker_punch.rb
CHANGED
data/lib/sucker_punch/queue.rb
CHANGED
@@ -68,7 +68,6 @@ module SuckerPunch
|
|
68
68
|
|
69
69
|
def self.shutdown_all
|
70
70
|
if SuckerPunch::RUNNING.make_false
|
71
|
-
SuckerPunch.logger.info("Shutdown triggered...executing remaining in-process jobs")
|
72
71
|
|
73
72
|
queues = all
|
74
73
|
latch = Concurrent::CountDownLatch.new(queues.length)
|
@@ -78,11 +77,9 @@ module SuckerPunch
|
|
78
77
|
queue.shutdown
|
79
78
|
end
|
80
79
|
|
81
|
-
|
82
|
-
SuckerPunch.logger.info("Remaining jobs have finished")
|
83
|
-
else
|
80
|
+
unless latch.wait(SuckerPunch.shutdown_timeout)
|
84
81
|
queues.each { |queue| queue.kill }
|
85
|
-
SuckerPunch.logger.info("
|
82
|
+
SuckerPunch.logger.info("Queued jobs didn't finish before shutdown_timeout...killing remaining jobs")
|
86
83
|
end
|
87
84
|
end
|
88
85
|
end
|
@@ -93,7 +90,8 @@ module SuckerPunch
|
|
93
90
|
:max_length,
|
94
91
|
:min_length,
|
95
92
|
:length,
|
96
|
-
:queue_length
|
93
|
+
:queue_length,
|
94
|
+
:wait_for_termination#,
|
97
95
|
#:idletime,
|
98
96
|
#:max_queue,
|
99
97
|
#:largest_length,
|
data/lib/sucker_punch/version.rb
CHANGED
data/sucker_punch.gemspec
CHANGED
@@ -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
|
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."
|
22
22
|
|
23
23
|
gem.add_development_dependency "rake", "~> 10.0"
|
24
24
|
gem.add_development_dependency "minitest"
|
@@ -15,7 +15,7 @@ module SuckerPunch
|
|
15
15
|
arr = Concurrent::Array.new
|
16
16
|
latch = Concurrent::CountDownLatch.new
|
17
17
|
FakeLatchJob.perform_async(arr, latch)
|
18
|
-
latch.wait(
|
18
|
+
latch.wait(1)
|
19
19
|
assert_equal 1, arr.size
|
20
20
|
end
|
21
21
|
|
@@ -24,7 +24,7 @@ module SuckerPunch
|
|
24
24
|
arr = Concurrent::Array.new
|
25
25
|
latch = Concurrent::CountDownLatch.new
|
26
26
|
FakeLatchJob.perform_async(arr, latch)
|
27
|
-
latch.wait(
|
27
|
+
latch.wait(1)
|
28
28
|
assert_equal 0, arr.size
|
29
29
|
end
|
30
30
|
|
@@ -32,7 +32,7 @@ module SuckerPunch
|
|
32
32
|
arr = Concurrent::Array.new
|
33
33
|
latch = Concurrent::CountDownLatch.new
|
34
34
|
FakeLatchJob.perform_in(0.1, arr, latch)
|
35
|
-
latch.wait(
|
35
|
+
latch.wait(1)
|
36
36
|
assert_equal 1, arr.size
|
37
37
|
end
|
38
38
|
|
@@ -41,7 +41,7 @@ module SuckerPunch
|
|
41
41
|
arr = Concurrent::Array.new
|
42
42
|
latch = Concurrent::CountDownLatch.new
|
43
43
|
FakeLatchJob.perform_in(0.1, arr, latch)
|
44
|
-
latch.wait(
|
44
|
+
latch.wait(1)
|
45
45
|
assert_equal 0, arr.size
|
46
46
|
end
|
47
47
|
|
@@ -84,34 +84,47 @@ module SuckerPunch
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def test_busy_workers_is_incremented_during_job_execution
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
job_class = Class.new(FakeBusyJob)
|
88
|
+
latch1 = Concurrent::CountDownLatch.new
|
89
|
+
latch2 = Concurrent::CountDownLatch.new
|
90
|
+
job_class.perform_async(latch1, latch2)
|
91
|
+
latch1.wait(1)
|
92
|
+
actual = SuckerPunch::Counter::Busy.new(job_class.to_s).value
|
93
|
+
latch2.count_down
|
94
|
+
assert actual > 0
|
90
95
|
end
|
91
96
|
|
92
97
|
def test_processed_jobs_is_incremented_on_successful_completion
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
latch.wait(
|
98
|
-
|
98
|
+
job_class = Class.new(FakeLatchJob)
|
99
|
+
jobs = 3
|
100
|
+
latch = Concurrent::CountDownLatch.new(jobs)
|
101
|
+
jobs.times{ job_class.perform_async([], latch) }
|
102
|
+
latch.wait(1)
|
103
|
+
queue = SuckerPunch::Queue.find_or_create(job_class.to_s)
|
104
|
+
queue.shutdown
|
105
|
+
queue.wait_for_termination(1)
|
106
|
+
assert SuckerPunch::Counter::Processed.new(job_class.to_s).value == jobs
|
99
107
|
end
|
100
108
|
|
101
109
|
def test_processed_jobs_is_incremented_when_enqueued_with_perform_in
|
110
|
+
job_class = Class.new(FakeLatchJob)
|
102
111
|
latch = Concurrent::CountDownLatch.new
|
103
|
-
|
104
|
-
latch.wait(
|
105
|
-
|
112
|
+
job_class.perform_in(0.0, [], latch)
|
113
|
+
latch.wait(1)
|
114
|
+
queue = SuckerPunch::Queue.find_or_create(job_class.to_s)
|
115
|
+
queue.shutdown
|
116
|
+
queue.wait_for_termination(1)
|
117
|
+
assert SuckerPunch::Counter::Processed.new(job_class.to_s).value == 1
|
106
118
|
end
|
107
119
|
|
108
120
|
def test_failed_jobs_is_incremented_when_job_raises
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
queue
|
113
|
-
|
114
|
-
|
121
|
+
job_class = Class.new(FakeErrorJob)
|
122
|
+
jobs = 3
|
123
|
+
jobs.times{ job_class.perform_async }
|
124
|
+
queue = SuckerPunch::Queue.find_or_create(job_class.to_s)
|
125
|
+
queue.shutdown
|
126
|
+
queue.wait_for_termination(1)
|
127
|
+
assert SuckerPunch::Counter::Failed.new(job_class.to_s).value == jobs
|
115
128
|
end
|
116
129
|
|
117
130
|
private
|
@@ -124,6 +137,16 @@ module SuckerPunch
|
|
124
137
|
end
|
125
138
|
end
|
126
139
|
|
140
|
+
class FakeBusyJob
|
141
|
+
include SuckerPunch::Job
|
142
|
+
def perform(latch1, latch2)
|
143
|
+
# trigger the first latch to tell the test we're working
|
144
|
+
latch1.count_down
|
145
|
+
# wait for the test to tell us we can finish
|
146
|
+
latch2.wait(1)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
127
150
|
class FakeSlowJob
|
128
151
|
include SuckerPunch::Job
|
129
152
|
def perform
|
@@ -30,7 +30,6 @@ module SuckerPunch
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_same_queue_is_returned_on_subsequent_queries
|
33
|
-
SuckerPunch::Queue::QUEUES.clear
|
34
33
|
queue = SuckerPunch::Queue.find_or_create(@queue)
|
35
34
|
assert_equal queue, SuckerPunch::Queue.find_or_create(@queue)
|
36
35
|
end
|
@@ -58,17 +57,13 @@ module SuckerPunch
|
|
58
57
|
end
|
59
58
|
|
60
59
|
def test_returns_queue_stats
|
61
|
-
latch = Concurrent::CountDownLatch.new
|
62
|
-
|
63
|
-
# run a job to setup workers
|
64
|
-
2.times { FakeNilJob.perform_async }
|
60
|
+
latch = Concurrent::CountDownLatch.new(2)
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
latch.wait(0.1)
|
62
|
+
2.times{ FakeLatchJob.perform_async(latch) }
|
63
|
+
latch.wait(2)
|
69
64
|
|
70
65
|
all_stats = SuckerPunch::Queue.stats
|
71
|
-
stats = all_stats[
|
66
|
+
stats = all_stats[FakeLatchJob.to_s]
|
72
67
|
assert stats["workers"]["total"] > 0
|
73
68
|
assert stats["workers"]["busy"] == 0
|
74
69
|
assert stats["workers"]["idle"] > 0
|
@@ -87,13 +82,72 @@ module SuckerPunch
|
|
87
82
|
assert_equal true, queue.running?
|
88
83
|
end
|
89
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
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_jobs_arent_posted_if_queue_isnt_running
|
94
|
+
arr = []
|
95
|
+
fake_pool = FakePool.new
|
96
|
+
queue = SuckerPunch::Queue.new "fake", fake_pool
|
97
|
+
queue.kill
|
98
|
+
queue.post(1, 2) { |args| arr.push args }
|
99
|
+
assert arr.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_kill_sends_kill_to_pool
|
103
|
+
fake_pool = FakePool.new
|
104
|
+
queue = SuckerPunch::Queue.new "fake", fake_pool
|
105
|
+
queue.kill
|
106
|
+
assert_equal :kill, fake_pool.signals.first
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_shutdown_sends_shutdown_to_pool
|
110
|
+
fake_pool = FakePool.new
|
111
|
+
queue = SuckerPunch::Queue.new "fake", fake_pool
|
112
|
+
queue.shutdown
|
113
|
+
assert_equal :shutdown, fake_pool.signals.first
|
114
|
+
end
|
115
|
+
|
90
116
|
private
|
91
117
|
|
118
|
+
class FakeLatchJob
|
119
|
+
include SuckerPunch::Job
|
120
|
+
def perform(latch)
|
121
|
+
latch.count_down
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
92
125
|
class FakeNilJob
|
93
126
|
include SuckerPunch::Job
|
94
127
|
def perform
|
95
128
|
nil
|
96
129
|
end
|
97
130
|
end
|
131
|
+
|
132
|
+
class FakePool
|
133
|
+
attr_accessor :signals
|
134
|
+
def initialize
|
135
|
+
@signals = []
|
136
|
+
end
|
137
|
+
|
138
|
+
def post(*args, &block)
|
139
|
+
if block_given?
|
140
|
+
block.call(args)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def kill
|
145
|
+
self.signals.push :kill
|
146
|
+
end
|
147
|
+
|
148
|
+
def shutdown
|
149
|
+
self.signals.push :shutdown
|
150
|
+
end
|
151
|
+
end
|
98
152
|
end
|
99
153
|
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.0.
|
4
|
+
version: 2.0.0.beta2
|
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-01-
|
11
|
+
date: 2016-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -106,9 +106,9 @@ homepage: https://github.com/brandonhilkert/sucker_punch
|
|
106
106
|
licenses:
|
107
107
|
- MIT
|
108
108
|
metadata: {}
|
109
|
-
post_install_message:
|
110
|
-
|
111
|
-
for details.
|
109
|
+
post_install_message: |-
|
110
|
+
Sucker Punch v2.0 introduces backwards-incompatible changes.
|
111
|
+
Please see https://github.com/brandonhilkert/sucker_punch/blob/master/CHANGES.md#20 for details.
|
112
112
|
rdoc_options: []
|
113
113
|
require_paths:
|
114
114
|
- lib
|