sucker_punch 2.0.0.beta1 → 2.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|