sucker_punch 2.0.4 → 2.1.0

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
- 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