sucker_punch 2.0.4 → 2.1.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
- SHA1:
3
- metadata.gz: 02222eadf72ce92d2552755c7bfb66332397c33e
4
- data.tar.gz: d3d339c4ad293760b2dd6f4e3eb3675758fc3a2f
2
+ SHA256:
3
+ metadata.gz: b3eb96d4ce859dbb4264aeb8a63383493cd76a62ae839a765882c4e8575ddb8a
4
+ data.tar.gz: 948e34c2f5b5ceb0574a43f59256128c8ffc7b3444cc19393b86e024088efef5
5
5
  SHA512:
6
- metadata.gz: eca020b9b49c2df52d474ba4d18b801c8f0723bda7a4a55bdecb23eb8fe886047b6765cf06939a8289a78a46471eebde8776b2a4caad96781013dc1ca589be8c
7
- data.tar.gz: d05ec8872904d0d9720b6d150375ad42d5a4c06aad5d271f58fa782e3171e26a8c01868b6e816d779e2c762c8dbddc12ec8f674a026108537af67e591ba2157b
6
+ metadata.gz: 3dd97ef36983eee4635601a81b093284f0e19d2203d297a76f18d4cd6293e4fcf119e43cdce14b0419e1cf0750cfc5cafda7f363c60b8023685210831ab6f2ed
7
+ data.tar.gz: e0e432152a7490dd3a2d32c157b4f9c7ef4f55bd22a3c6a9417d5b8a4b221adc78a83d64977f82d3615819def5ec1f5f806ad73c43003dccbdad7ad192d25c61
data/CHANGES.md CHANGED
@@ -1,3 +1,26 @@
1
+ 2.1.0
2
+ -------
3
+ - Add `max_jobs` configuration option to set the maximum number of tasks that
4
+ may be waiting in the work queue
5
+
6
+ ```ruby
7
+ class JobWithLimit
8
+ include SuckerPunch::Job
9
+ max_jobs 2
10
+
11
+ def perform(data)
12
+ # work...
13
+ end
14
+ end
15
+
16
+ 10.times do
17
+ begin
18
+ JobWithLimit.perform_async('work') }
19
+ rescue Concurrent::RejectedExecutionError => e
20
+ # Queue maxed out, this job didn't get queued
21
+ end
22
+ end
23
+
1
24
  2.0.4
2
25
  -------
3
26
  - Better initialization of variables and names to remove warnings
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Sucker Punch
2
2
 
3
- [![Build Status](https://travis-ci.org/brandonhilkert/sucker_punch.png?branch=master)](https://travis-ci.org/brandonhilkert/sucker_punch)
4
- [![Code Climate](https://codeclimate.com/github/brandonhilkert/sucker_punch.png)](https://codeclimate.com/github/brandonhilkert/sucker_punch)
3
+ [![Build Status](https://travis-ci.org/brandonhilkert/sucker_punch.svg?branch=master)](https://travis-ci.org/brandonhilkert/sucker_punch)
4
+ [![Code Climate](https://codeclimate.com/github/brandonhilkert/sucker_punch.svg)](https://codeclimate.com/github/brandonhilkert/sucker_punch)
5
5
 
6
6
  Sucker Punch is a single-process Ruby asynchronous processing library.
7
7
  This reduces costs
@@ -114,6 +114,22 @@ class LogJob
114
114
  end
115
115
  ```
116
116
 
117
+ #### Configure the Queue Size
118
+
119
+ The default number of jobs that can be queued is unlimited. If you wish to restrict this you can set
120
+ max\_jobs as follows:
121
+
122
+ ```Ruby
123
+ class LogJob
124
+ include SuckerPunch::Job
125
+ max_jobs 10
126
+
127
+ def perform(event)
128
+ Log.new(event).track
129
+ end
130
+ end
131
+ ```
132
+
117
133
  #### Executing Jobs in the Future
118
134
 
119
135
  Many background processing libraries have methods to perform operations after a
@@ -254,6 +270,19 @@ $ rails g sucker_punch:job logger
254
270
  would create the file `app/jobs/logger_job.rb` with a unimplemented `#perform`
255
271
  method.
256
272
 
273
+ ## Sinatra
274
+
275
+ If you're using Sucker Punch with Sinatra, you must require Sucker Punch before Sinatra:
276
+
277
+ ```ruby
278
+ # app.rb
279
+
280
+ require 'sucker_punch'
281
+ require 'sinatra'
282
+ ```
283
+
284
+ This will ensure Sucker Punch's `at_exit()` handler to clean up and shutdown queues does not happen **before** Sinatra *starts up* via its own `at_exit()` handler.
285
+
257
286
  ## Active Job
258
287
 
259
288
  Sucker Punch has been added as an Active Job adapter in Rails 4.2.
@@ -21,8 +21,10 @@ module SuckerPunch
21
21
  def self.included(base)
22
22
  base.extend(ClassMethods)
23
23
  base.class_attribute :num_workers
24
+ base.class_attribute :num_jobs_max
24
25
 
25
26
  base.num_workers = 2
27
+ base.num_jobs_max = nil
26
28
  end
27
29
 
28
30
  def logger
@@ -32,13 +34,13 @@ module SuckerPunch
32
34
  module ClassMethods
33
35
  def perform_async(*args)
34
36
  return unless SuckerPunch::RUNNING.true?
35
- queue = SuckerPunch::Queue.find_or_create(self.to_s, num_workers)
37
+ queue = SuckerPunch::Queue.find_or_create(self.to_s, num_workers, num_jobs_max)
36
38
  queue.post(args) { |job_args| __run_perform(*job_args) }
37
39
  end
38
40
 
39
41
  def perform_in(interval, *args)
40
42
  return unless SuckerPunch::RUNNING.true?
41
- queue = SuckerPunch::Queue.find_or_create(self.to_s, num_workers)
43
+ queue = SuckerPunch::Queue.find_or_create(self.to_s, num_workers, num_jobs_max)
42
44
  job = Concurrent::ScheduledTask.execute(interval.to_f, args: args, executor: queue) do
43
45
  __run_perform(*args)
44
46
  end
@@ -49,6 +51,10 @@ module SuckerPunch
49
51
  self.num_workers = num
50
52
  end
51
53
 
54
+ def max_jobs(num)
55
+ self.num_jobs_max = num
56
+ end
57
+
52
58
  def __run_perform(*args)
53
59
  SuckerPunch::Counter::Busy.new(self.to_s).increment
54
60
  result = self.new.perform(*args)
@@ -5,22 +5,25 @@ module SuckerPunch
5
5
  extend Forwardable
6
6
  include Concurrent::ExecutorService
7
7
 
8
+ DEFAULT_MAX_QUEUE_SIZE = 0 # Unlimited
9
+
8
10
  DEFAULT_EXECUTOR_OPTIONS = {
9
11
  min_threads: 2,
10
12
  max_threads: 2,
11
13
  idletime: 60, # 1 minute
12
- max_queue: 0, # unlimited
13
14
  auto_terminate: false # Let shutdown modes handle thread termination
14
15
  }.freeze
15
16
 
16
17
  QUEUES = Concurrent::Map.new
17
18
 
18
- def self.find_or_create(name, num_workers = 2)
19
+ def self.find_or_create(name, num_workers = 2, num_jobs_max = nil)
19
20
  pool = QUEUES.fetch_or_store(name) do
20
- options = DEFAULT_EXECUTOR_OPTIONS.merge({
21
- min_threads: num_workers,
22
- max_threads: num_workers
23
- })
21
+ options = DEFAULT_EXECUTOR_OPTIONS
22
+ .merge(
23
+ min_threads: num_workers,
24
+ max_threads: num_workers,
25
+ max_queue: num_jobs_max || DEFAULT_MAX_QUEUE_SIZE
26
+ )
24
27
  Concurrent::ThreadPoolExecutor.new(options)
25
28
  end
26
29
 
@@ -111,6 +114,7 @@ module SuckerPunch
111
114
  def_delegators :@pool,
112
115
  :max_length,
113
116
  :min_length,
117
+ :max_queue,
114
118
  :length,
115
119
  :queue_length,
116
120
  :wait_for_termination#,
@@ -1,3 +1,3 @@
1
1
  module SuckerPunch
2
- VERSION = "2.0.4"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -55,6 +55,11 @@ module SuckerPunch
55
55
  FakeLogJob.workers(2)
56
56
  end
57
57
 
58
+ def test_can_set_max_jobs
59
+ FakeLogJob.max_jobs(10)
60
+ assert_equal 10, FakeLogJob.num_jobs_max
61
+ end
62
+
58
63
  def test_logger_is_accessible_from_instance
59
64
  SuckerPunch.logger = SuckerPunch.default_logger
60
65
  assert_equal SuckerPunch.logger, FakeLogJob.new.logger
@@ -29,6 +29,11 @@ module SuckerPunch
29
29
  assert_equal 4, queue.min_length
30
30
  end
31
31
 
32
+ def test_queue_max_queue_can_be_set
33
+ queue = SuckerPunch::Queue.find_or_create(@queue, 4, 10)
34
+ assert_equal(10, queue.max_queue)
35
+ end
36
+
32
37
  def test_same_queue_is_returned_on_subsequent_queries
33
38
  queue = SuckerPunch::Queue.find_or_create(@queue)
34
39
  assert_equal queue, SuckerPunch::Queue.find_or_create(@queue)
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.4
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Hilkert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-15 00:00:00.000000000 Z
11
+ date: 2018-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  version: '0'
121
121
  requirements: []
122
122
  rubyforge_project:
123
- rubygems_version: 2.6.13
123
+ rubygems_version: 2.7.6
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: Sucker Punch is a Ruby asynchronous processing using concurrent-ruby, heavily