resque-restriction 0.6.0 → 0.7.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: 135cae91708b3d84ff8c6feafdb715e7043893ec
4
- data.tar.gz: c4d04692d1b62a3b0bf8dc797a1c679965e05c69
2
+ SHA256:
3
+ metadata.gz: 681852b48ac3fb45d6a5d1806af5617d6c4c566ee6483c777d1e7d1e837443ba
4
+ data.tar.gz: '0706749a9fc0beb80cb532a84e5988157055759b0151e48b1a08d2fa8c515b21'
5
5
  SHA512:
6
- metadata.gz: e0640880f52054dcfee91e434373a2db2b1cd5f61997fbaaefedce2d59f3647fb10ca0d921afd541c0fb2310ad8b29befe5d7f35c080e55be8d50183db089130
7
- data.tar.gz: ecb9750f0198139276220ccb85178d09c44f824eba13bf83c3b11e8f3313c837f83f24064a65ca8a43de3b34f6fffc546ade0f5bc890052a88283e1075924876
6
+ metadata.gz: 2015e5527ba932161e0cdfbf20efb102214403232f5595f496571df3b8964d5157bef27fa21e3feb2363f89fbf502576c8b13596b9322ef61873861669c71a32
7
+ data.tar.gz: b7fce8d53acc85f50d6c21626b03e7aed86a5f04d0cd01f3a40301ff2534ae149bf3caf7cd53a5e093765a25d233c06ff6819f733f7fcc502a7586d1ac940ec9
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.3
5
+ before_install: gem install bundler -v 1.16.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ### Unreleased
2
2
 
3
+ # 0.7.0 (2021-06-06)
4
+
5
+ * Support `per_second`
6
+ * Reduce Redis thrashing on large restriction queues
7
+
3
8
  # 0.6.0
4
9
 
5
10
  * support customized period like `per_minute_and_user_id`
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  resque-restriction
2
2
  ===============
3
3
 
4
+ [![AwesomeCode Status for flyerhzm/resque-restriction](https://awesomecode.io/projects/ebc1a493-78f5-4d8a-9bb7-097fdaa657ec/status)](https://awesomecode.io/repos/flyerhzm/resque-restriction)
5
+ [![Build Status](https://secure.travis-ci.org/flyerhzm/resque-restriction.png)](http://travis-ci.org/flyerhzm/resque-restriction)
6
+
4
7
  Resque Restriction is a plugin for the [Resque](https://github.com/resque/resque) queueing system. It adds two functions:
5
8
 
6
9
  1. it will limit the execution number of certain jobs in a period time. For example, it can limit a certain job can be executed 1000 times per day, 100 time per hour and 30 times per 300 seconds.
@@ -52,11 +55,13 @@ end
52
55
 
53
56
  That means the InvitationJob can not be executed more than 1000 times per day, 100 times per hour and 30 times per 300 seconds. All restrictions have to be met for the job to execute.
54
57
 
55
- The argument of restrict method is a hash, the key of the hash is a period time, including :concurrent, :per_minute, :per_hour, :per_day, :per_week, :per_month, :per_year, and you can also define any period like :per_300 means per 300 seconds. The value of the hash is the job execution limit number in a period. The :concurrent option restricts the number of jobs that run simultaneously.
58
+ The argument of restrict method is a hash, the key of the hash is a period time, including :concurrent, :per_second, :per_minute, :per_hour, :per_day, :per_week, :per_month, :per_year, and you can also define any period like :per_300 means per 300 seconds. The value of the hash is the job execution limit number in a period. The :concurrent option restricts the number of jobs that run simultaneously.
56
59
 
57
60
  Advance
58
61
  -------
59
62
 
63
+ ### Custom Restrictions
64
+
60
65
  You can also add customized restriction as you like. For example, we have a job to restrict the facebook post numbers 40 times per user per day, we can define as:
61
66
 
62
67
 
@@ -89,6 +94,17 @@ end
89
94
 
90
95
  options["user_id"] returns the user's facebook uid, the key point is that the different restriction_identifiers can restrict different job execution numbers.
91
96
 
97
+ ### Reducing Redis Thrashing
98
+
99
+ With large restriction queues (1,000+ jobs), Redis is hit with a large number of `Resque.pop` and re-enqueue calls which puts the job immediately back into the restriction queue. That process translates to extraneous Redis requests.
100
+
101
+ To avoid the extraneous Redis calls, configure `max_queue_peek`. An appropriate `max_queue_peek` value depends on your application, number of workers, job processing time, and peek jobs in the queue. By default `max_queue_peek` is disabled.
102
+
103
+ ```ruby
104
+ Resque::Restriction.configure do |config|
105
+ config.max_queue_peek = 100 # jobs
106
+ end
107
+ ```
92
108
 
93
109
  Contributing
94
110
  ------------
data/Rakefile CHANGED
@@ -3,5 +3,4 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
7
-
6
+ task default: :spec
@@ -7,8 +7,8 @@ module Resque
7
7
  if queue =~ /^#{Plugins::Restriction::RESTRICTION_QUEUE_PREFIX}/
8
8
  # If processing the restriction queue, when poping and pushing to end,
9
9
  # we can't tell when we reach the original one, so just walk the length
10
- # of the queue so we don't run infinitely long
11
- Resque.size(queue).times do |i|
10
+ # of the queue or up to max_queue_peek so we don't run infinitely long
11
+ [Resque.size(queue), Restriction.config.max_queue_peek(queue)].compact.min.times do
12
12
  # For the job at the head of the queue, repush to restricition queue
13
13
  # if still restricted, otherwise we have a runnable job, so create it
14
14
  # and return
@@ -19,7 +19,7 @@ module Resque
19
19
  end
20
20
  end
21
21
  end
22
- return nil
22
+ nil
23
23
  else
24
24
  # drop through to original Job::Reserve if not restriction queue
25
25
  origin_reserve(queue)
@@ -2,6 +2,7 @@ module Resque
2
2
  module Plugins
3
3
  module Restriction
4
4
  SECONDS = {
5
+ :per_second => 1,
5
6
  :per_minute => 60,
6
7
  :per_hour => 60*60,
7
8
  :per_day => 24*60*60,
@@ -67,7 +68,7 @@ module Resque
67
68
  period_key, custom_key = period.to_s.split('_and_')
68
69
  period_str = case period_key.to_sym
69
70
  when :concurrent then "*"
70
- when :per_minute, :per_hour, :per_day, :per_week then (Time.now.to_i / SECONDS[period_key.to_sym]).to_s
71
+ when :per_second, :per_minute, :per_hour, :per_day, :per_week then (Time.now.to_i / SECONDS[period_key.to_sym]).to_s
71
72
  when :per_month then Date.today.strftime("%Y-%m")
72
73
  when :per_year then Date.today.year.to_s
73
74
  else period_key =~ /^per_(\d+)$/ and (Time.now.to_i / $1.to_i).to_s end
@@ -1,3 +1,4 @@
1
1
  require 'resque'
2
+ require 'resque/restriction/config'
2
3
  require 'resque/plugins/job'
3
4
  require 'resque/plugins/restriction'
@@ -0,0 +1,49 @@
1
+ module Resque
2
+ module Restriction
3
+ def self.configure
4
+ yield config
5
+ end
6
+
7
+ def self.config
8
+ @config ||= Config.new
9
+ end
10
+
11
+ class Config
12
+ def initialize
13
+ @max_queue_peek = nil
14
+ end
15
+
16
+ def max_queue_peek=(value_or_callable)
17
+ if value_or_callable.respond_to?(:call)
18
+ @max_queue_peek = value_or_callable
19
+ elsif value_or_callable.nil?
20
+ @max_queue_peek = nil
21
+ else
22
+ @max_queue_peek = validated_max_queue_peek(value_or_callable)
23
+ end
24
+ end
25
+
26
+ def max_queue_peek(queue)
27
+ @max_queue_peek.respond_to?(:call) ? @max_queue_peek.call(queue) : @max_queue_peek
28
+ end
29
+
30
+ private
31
+
32
+ def validated_max_queue_peek(value)
33
+ peek = nil
34
+
35
+ begin
36
+ peek = Integer(value)
37
+
38
+ if peek <= 0
39
+ raise ArgumentError
40
+ end
41
+ rescue ArgumentError
42
+ raise ArgumentError, "max_queue_peek should be either nil or an Integer greater than 0 but #{value.inspect} was provided"
43
+ end
44
+
45
+ peek
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,5 @@
1
1
  module Resque
2
2
  module Restriction
3
- VERSION = '0.6.0'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
@@ -1,12 +1,12 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "resque/restriction/version"
3
+ require 'resque/restriction/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "resque-restriction"
6
+ spec.name = 'resque-restriction'
7
7
  spec.version = Resque::Restriction::VERSION
8
- spec.authors = ["Richard Huang"]
9
- spec.email = ["flyerhzm@gmail.com"]
8
+ spec.authors = ['Richard Huang']
9
+ spec.email = ['flyerhzm@gmail.com']
10
10
 
11
11
  spec.summary = 'resque-restriction is an extension to resque queue system that restricts the execution number of certain jobs in a period time.'
12
12
  spec.description = 'resque-restriction is an extension to resque queue system that restricts the execution number of certain jobs in a period time, the exceeded jobs will be executed at the next period.'
@@ -15,12 +15,12 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
16
  f.match(%r{^(test|spec|features)/})
17
17
  end
18
- spec.bindir = "exe"
18
+ spec.bindir = 'exe'
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
20
+ spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.16"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- spec.add_development_dependency "resque", ">= 1.7.0"
22
+ spec.add_development_dependency 'bundler'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'resque', '>= 1.7.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
26
  end
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-restriction
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-14 00:00:00.000000000 Z
11
+ date: 2021-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: resque
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: 1.7.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: 1.7.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: resque
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.7.0
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.7.0
68
+ version: '3.0'
69
69
  description: resque-restriction is an extension to resque queue system that restricts
70
70
  the execution number of certain jobs in a period time, the exceeded jobs will be
71
71
  executed at the next period.
@@ -76,6 +76,7 @@ extensions: []
76
76
  extra_rdoc_files: []
77
77
  files:
78
78
  - ".gitignore"
79
+ - ".travis.yml"
79
80
  - CHANGELOG.md
80
81
  - Gemfile
81
82
  - LICENSE
@@ -84,12 +85,13 @@ files:
84
85
  - lib/resque/plugins/job.rb
85
86
  - lib/resque/plugins/restriction.rb
86
87
  - lib/resque/restriction.rb
88
+ - lib/resque/restriction/config.rb
87
89
  - lib/resque/restriction/version.rb
88
90
  - resque-restriction.gemspec
89
91
  homepage: https://github.com/flyerhzm/resque-restriction
90
92
  licenses: []
91
93
  metadata: {}
92
- post_install_message:
94
+ post_install_message:
93
95
  rdoc_options: []
94
96
  require_paths:
95
97
  - lib
@@ -104,9 +106,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
106
  - !ruby/object:Gem::Version
105
107
  version: '0'
106
108
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.6.14
109
- signing_key:
109
+ rubygems_version: 3.1.6
110
+ signing_key:
110
111
  specification_version: 4
111
112
  summary: resque-restriction is an extension to resque queue system that restricts
112
113
  the execution number of certain jobs in a period time.