full_throttle 0.0.1 → 0.0.3

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
2
  SHA1:
3
- metadata.gz: 452b5545989069904cecc0d3ef959653fc9d21df
4
- data.tar.gz: 3a83890b6ca55ce24fb3edfe8dfeb7d462f09fb9
3
+ metadata.gz: b46c0880281fcab9692c92cc16af9744b558af25
4
+ data.tar.gz: dbd5096b50d090cb1cb9e598fcedef8548c56324
5
5
  SHA512:
6
- metadata.gz: dce830e7b8cb7a47a8459803255f355a635b69c0f2fea4558cbf9ffa97dc9b7d75b9e5612ddad575805884d9061ec04155fbd75ecd0f63b5f0cb335322c89d97
7
- data.tar.gz: 83434f7de365a34edc82a3e0cec07d2bcf487a4cd9d30221f074d25e5ec0741594e0758506d9e3ac46f6d18ade72ba31e1f25e22304a9858c007c74f8096b372
6
+ metadata.gz: 13584c7e550fc25474d98f45da57177f848d53017c310f207ea3aff6464c4500e72aa6299d678df1e1151913eb929e5247893610df642505c99a59536ae9196b
7
+ data.tar.gz: 090680a38e771d545bbd26d8035677b4e7f0b2d49a401c4e37656cd42b3abfbac1c2064151ee813f085925a84bee50b0c1eb9e11f12e797b3a33a4729fa0dd3c
data/README.md CHANGED
@@ -1,6 +1,45 @@
1
- # Throttle
1
+ # Full Throttle
2
+
3
+ ![](http://www.necessarygames.com/sites/default/files/game_teaser_images/full_throttle_teaser.png)
4
+
5
+ Pull the breaks on your background processing, protect api calls from abuse, and manage throughput with 0 hassle leveraging Redis to throttle concurrent processes.
6
+
7
+ Atomicity and thread-safety of throttle guaranteed by good use of Redis.
8
+
9
+ ## Usage
10
+
11
+ ```ruby
12
+ response = Throttle.for(:user_info, 200) { api["users/#{id}"].get }
13
+ user.update(response)
14
+ ```
15
+
16
+ There we have `:user_info` is the id of the throttle, `200` is the number of times that id can be executed in one second. *Full Throttle* is designed for high speed action, not long throttling windows.
17
+
18
+ __get updated status__
19
+
20
+ ```ruby
21
+ instance = Throttle.for(:user_info)
22
+ instance.status # [ bucket_time, bucket_count, bucket_size ]
23
+ ```
24
+
25
+ __handle or log throttled actions__
26
+
27
+ ```ruby
28
+ begin
29
+ Throttle.for(:search_index, 300) { record.update_index! }
30
+ rescue Throttle::ThrottledError => e
31
+ ...
32
+ end
33
+ ```
34
+
35
+ __manage throughput without code pushes__ running on the console or on a cronjob to raise the limits at night and take it easy during the day
36
+
37
+ ```ruby
38
+ if (22...7).include?(Time.now.hour)
39
+ Throttle.for(:upstream_sync).set_bucket_size!(500)
40
+ end
41
+ ```
2
42
 
3
- TODO: Write a gem description
4
43
 
5
44
  ## Installation
6
45
 
@@ -18,13 +57,9 @@ Or install it yourself as:
18
57
 
19
58
  $ gem install throttle
20
59
 
21
- ## Usage
22
-
23
- TODO: Write usage instructions here
24
-
25
60
  ## Contributing
26
61
 
27
- 1. Fork it ( https://github.com/[my-github-username]/throttle/fork )
62
+ 1. Fork it ( https://github.com/rafaelbandeira3/full_throttle/fork )
28
63
  2. Create your feature branch (`git checkout -b my-new-feature`)
29
64
  3. Commit your changes (`git commit -am 'Add some feature'`)
30
65
  4. Push to the branch (`git push origin my-new-feature`)
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "redis", "~> 3.0.0"
21
+ spec.add_dependency "redis", "~> 3.0"
22
22
  spec.add_development_dependency "bundler", "~> 1.7"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec", "~> 2.3"
@@ -12,7 +12,7 @@ module Throttle
12
12
  :default_ns,
13
13
  :default_polling
14
14
 
15
- def for(key, max_per_second, opts = {}, &block)
15
+ def for(key, max_per_second = nil, opts = {}, &block)
16
16
  polling = opts[:polling] || Throttle.default_polling
17
17
  timeout = opts[:timeout] || Throttle.default_timeout
18
18
  redis = opts[:redis] || Throttle.default_redis_client
@@ -22,7 +22,7 @@ module Throttle
22
22
  strategy.set_bucket_size!
23
23
 
24
24
  instance = Instance.new(strategy, polling, timeout)
25
- instance.limit(&block)
25
+ block_given? ? instance.limit(&block) : instance
26
26
  end
27
27
  end
28
28
  end
@@ -1,3 +1,3 @@
1
1
  module Throttle
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -34,29 +34,49 @@ describe Throttle::RedisScript do
34
34
  end
35
35
 
36
36
  describe "acquiring permission" do
37
- before(:each) { subject.set_bucket_size! }
38
-
39
- it "acquires entry on bucket if possible and returns time, count and flag" do
40
- Timecop.freeze(time) do |t|
41
- expect(subject.acquire).to eq [true, 1, t.to_i]
42
- expect(subject.acquire).to eq [true, 2, t.to_i]
43
- expect(subject.acquire).to eq [true, 3, t.to_i]
44
- expect(subject.acquire).to eq [false, 3, t.to_i]
45
- expect(subject.acquire).to eq [false, 3, t.to_i]
46
- end
37
+ before(:each) { Timecop.freeze(time) }
38
+ after(:each) { Timecop.return }
39
+
40
+ it "returns time, count and flag" do
41
+ expect(subject.acquire).to eq [true, 1, time.to_i]
47
42
  end
48
43
 
49
- it "changes bucket size at runtime" do
50
- Timecop.freeze(time) do |t|
51
- expect(subject.acquire).to eq [true, 1, t.to_i]
52
- expect(subject.acquire).to eq [true, 2, t.to_i]
53
- expect(subject.acquire).to eq [true, 3, t.to_i]
54
- expect(subject.acquire).to eq [false, 3, t.to_i]
44
+ context do
45
+ before(:each) { subject.set_bucket_size! }
46
+ it "acquires entry on bucket isn't full" do
47
+ expect(subject.acquire).to eq [true, 1, time.to_i]
48
+ expect(subject.acquire).to eq [true, 2, time.to_i]
49
+ expect(subject.acquire).to eq [true, 3, time.to_i]
50
+ expect(subject.acquire).to eq [false, 3, time.to_i]
51
+ expect(subject.acquire).to eq [false, 3, time.to_i]
52
+ end
53
+
54
+ it "empties bucket after bucket duration" do
55
+ expect(subject.acquire).to eq [true, 1, time.to_i]
56
+ expect(subject.acquire).to eq [true, 2, time.to_i]
57
+ expect(subject.acquire).to eq [true, 3, time.to_i]
58
+ expect(subject.acquire).to eq [false, 3, time.to_i]
59
+
60
+ Timecop.freeze(time + 1)
61
+ expect(subject.acquire).to eq [true, 1, (time + 1).to_i]
62
+ end
63
+
64
+ it "changes bucket size at runtime" do
65
+ expect(subject.acquire).to eq [true, 1, time.to_i]
66
+ expect(subject.acquire).to eq [true, 2, time.to_i]
67
+ expect(subject.acquire).to eq [true, 3, time.to_i]
68
+ expect(subject.acquire).to eq [false, 3, time.to_i]
55
69
 
56
70
  subject.set_bucket_size!(4)
57
- expect(subject.acquire).to eq [true, 4, t.to_i]
71
+ expect(subject.acquire).to eq [true, 4, time.to_i]
58
72
  end
59
73
  end
74
+
75
+ it "acquires always if no size set" do
76
+ credibility = ENV["CREDIBLE"] ? Float::INFINITY : 20
77
+
78
+ (0..credibility).each {|n| expect(subject.acquire).to eq [true, n + 1, time.to_i] }
79
+ end
60
80
  end
61
81
  end
62
82
  end
@@ -11,7 +11,7 @@ describe Throttle do
11
11
  let(:opts) { {} }
12
12
 
13
13
  shared_examples "Throttle API" do
14
- it "initializes throttle with options and limits given block" do
14
+ before(:each) do
15
15
  expect(described_class::RedisScript).to receive(:new).
16
16
  with(redis, "#{ns}:#{key}", max).
17
17
  and_call_original
@@ -19,9 +19,14 @@ describe Throttle do
19
19
  expect(described_class::Instance).to receive(:new).
20
20
  with(kind_of(described_class::RedisScript), polling, timeout).
21
21
  and_call_original
22
+ end
22
23
 
23
- expect(counter).to receive(:count)
24
+ it "initializes throttle with options" do
25
+ expect(described_class.for(key, max, opts)).to be_a(described_class::Instance)
26
+ end
24
27
 
28
+ it "initializes and returns limit" do
29
+ expect(counter).to receive(:count)
25
30
  described_class.for(key, max, opts) { counter.count }
26
31
  end
27
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: full_throttle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Bandeira
@@ -14,70 +14,70 @@ dependencies:
14
14
  name: redis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
19
+ version: '3.0'
20
20
  type: :runtime
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: 3.0.0
26
+ version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.7'
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
40
  version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.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
54
  version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '2.3'
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
68
  version: '2.3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: timecop
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ~>
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.7.1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.7.1
83
83
  description: Redis based throttle mechanism to be used by concurrent background jobs
@@ -113,17 +113,17 @@ require_paths:
113
113
  - lib
114
114
  required_ruby_version: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - ">="
116
+ - - '>='
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - ">="
121
+ - - '>='
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  requirements: []
125
125
  rubyforge_project:
126
- rubygems_version: 2.4.1
126
+ rubygems_version: 2.0.14
127
127
  signing_key:
128
128
  specification_version: 4
129
129
  summary: Throttle mechanism for distributed work
@@ -132,4 +132,3 @@ test_files:
132
132
  - spec/lib/throttle/redis_script_spec.rb
133
133
  - spec/lib/throttle_spec.rb
134
134
  - spec/spec_helper.rb
135
- has_rdoc: