ratelimit-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6cf58e13eb3d3e2371dc2dd10833cf597d2ab108
4
+ data.tar.gz: 24eb31d4a576763298d489bfe6d11454f7c5eb8e
5
+ SHA512:
6
+ metadata.gz: df86c38c7dd3b1c57f7ed345e245aac1b9962df2f831e2daab790b3c34bae842e9e75bd0e85d08c435e61c516a3f7ff94aba56283d5370cf380c8b464ae83e50
7
+ data.tar.gz: fcd2f9261d6c38bfc779055baac475b26e3a8fa5fe9d88f7a68aa7e28690f850286137ef0cd28c96fd32e9ad08c1ab711727971aec5ba5377ee115fe41fb5a0a
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ ratelimit-ruby
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "https://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ gem 'faraday'
9
+ gem 'faraday_middleware'
10
+
11
+ group :development do
12
+ gem "shoulda", ">= 0"
13
+ gem "rdoc", "~> 3.12"
14
+ gem "bundler", "~> 1.0"
15
+ gem "juwelier", "~> 2.1.0"
16
+ gem "simplecov", ">= 0"
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,87 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (5.0.0.1)
5
+ concurrent-ruby (~> 1.0, >= 1.0.2)
6
+ i18n (~> 0.7)
7
+ minitest (~> 5.1)
8
+ tzinfo (~> 1.1)
9
+ addressable (2.4.0)
10
+ builder (3.2.2)
11
+ concurrent-ruby (1.0.2)
12
+ descendants_tracker (0.0.4)
13
+ thread_safe (~> 0.3, >= 0.3.1)
14
+ docile (1.1.5)
15
+ faraday (0.9.2)
16
+ multipart-post (>= 1.2, < 3)
17
+ faraday_middleware (0.10.0)
18
+ faraday (>= 0.7.4, < 0.10)
19
+ git (1.3.0)
20
+ github_api (0.14.5)
21
+ addressable (~> 2.4.0)
22
+ descendants_tracker (~> 0.0.4)
23
+ faraday (~> 0.8, < 0.10)
24
+ hashie (>= 3.4)
25
+ oauth2 (~> 1.0)
26
+ hashie (3.4.6)
27
+ highline (1.7.8)
28
+ i18n (0.7.0)
29
+ json (1.8.3)
30
+ juwelier (2.1.3)
31
+ builder
32
+ bundler (>= 1.13)
33
+ git (>= 1.2.5)
34
+ github_api
35
+ highline (>= 1.6.15)
36
+ nokogiri (>= 1.5.10)
37
+ rake
38
+ rdoc
39
+ semver
40
+ jwt (1.5.6)
41
+ mini_portile2 (2.1.0)
42
+ minitest (5.9.1)
43
+ multi_json (1.12.1)
44
+ multi_xml (0.5.5)
45
+ multipart-post (2.0.0)
46
+ nokogiri (1.6.8.1)
47
+ mini_portile2 (~> 2.1.0)
48
+ oauth2 (1.2.0)
49
+ faraday (>= 0.8, < 0.10)
50
+ jwt (~> 1.0)
51
+ multi_json (~> 1.3)
52
+ multi_xml (~> 0.5)
53
+ rack (>= 1.2, < 3)
54
+ rack (2.0.1)
55
+ rake (11.3.0)
56
+ rdoc (3.12.2)
57
+ json (~> 1.4)
58
+ semver (1.0.1)
59
+ shoulda (3.5.0)
60
+ shoulda-context (~> 1.0, >= 1.0.1)
61
+ shoulda-matchers (>= 1.4.1, < 3.0)
62
+ shoulda-context (1.2.1)
63
+ shoulda-matchers (2.8.0)
64
+ activesupport (>= 3.0.0)
65
+ simplecov (0.12.0)
66
+ docile (~> 1.1.0)
67
+ json (>= 1.8, < 3)
68
+ simplecov-html (~> 0.10.0)
69
+ simplecov-html (0.10.0)
70
+ thread_safe (0.3.5)
71
+ tzinfo (1.2.2)
72
+ thread_safe (~> 0.1)
73
+
74
+ PLATFORMS
75
+ ruby
76
+
77
+ DEPENDENCIES
78
+ bundler (~> 1.0)
79
+ faraday
80
+ faraday_middleware
81
+ juwelier (~> 2.1.0)
82
+ rdoc (~> 3.12)
83
+ shoulda
84
+ simplecov
85
+
86
+ BUNDLED WITH
87
+ 1.13.6
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 Jeff Dwyer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # ratelimit-ruby
2
+
3
+ Rate Limit your Ruby app using http://www.ratelim.it
4
+
5
+ ```ruby
6
+ limiter = RateLimit::Limiter.new(apikey: "APIKEY", account_id: ACCT_ID)
7
+
8
+ # only need to do this on startup
9
+ # limit to 1 per hour
10
+ limiter.upsert_limit(Limit.new("pageload", 1, RateLimIt::HOURLY_ROLLING))
11
+
12
+ if limiter.check?("pageload")
13
+ do_hourly_thing()
14
+ end
15
+ ```
16
+ See full documentation http://www.ratelim.it/documentation
17
+
18
+ ## Supports
19
+
20
+ * RateLimits
21
+ * Millions of individual limits sharing the same policies
22
+ * WebUI for tweaking limits
23
+ * Logging
24
+ * Semaphores
25
+ * Infinite retention fo deduplication workflows
26
+
27
+
28
+ ## Contributing to ratelimit-ruby
29
+
30
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
31
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
32
+ * Fork the project.
33
+ * Start a feature/bugfix branch.
34
+ * Commit and push until you are happy with your contribution.
35
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
36
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
37
+
38
+ ## Copyright
39
+
40
+ Copyright (c) 2016 Jeff Dwyer. See LICENSE.txt for
41
+ further details.
42
+
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'juwelier'
15
+ Juwelier::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "ratelimit-ruby"
18
+ gem.homepage = "http://github.com/jdwyah/ratelimit-ruby"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{rate limit your ruby}
21
+ gem.description = %Q{rate limit your ruby}
22
+ gem.email = "jdwyah@gmail.com"
23
+ gem.authors = ["Jeff Dwyer"]
24
+
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Juwelier::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ desc "Code coverage detail"
37
+ task :simplecov do
38
+ ENV['COVERAGE'] = "true"
39
+ Rake::Task['test'].execute
40
+ end
41
+
42
+ task :default => :test
43
+
44
+ require 'rdoc/task'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "ratelimit-ruby #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,24 @@
1
+ module RateLimit
2
+ SECONDLY="SECONDLY".freeze
3
+ MINUTELY="MINUTELY".freeze
4
+ MINUTELY_ROLLING="MINUTELY_ROLLING".freeze
5
+ HOURLY="HOURLY".freeze
6
+ HOURLY_ROLLING="HOURLY_ROLLING".freeze
7
+ DAILY="DAILY".freeze
8
+ DAILY_ROLLING="DAILY_ROLLING".freeze
9
+ MONTHLY="MONTHLY".freeze
10
+ INFINITE="INFINITE".freeze
11
+ POLICIES = [SECONDLY, MINUTELY, MINUTELY_ROLLING, HOURLY, HOURLY_ROLLING, DAILY, DAILY_ROLLING, MINUTELY, INFINITE]
12
+
13
+ class LimitDefinition
14
+ attr_reader :limit, :group, :policy, :returnable
15
+
16
+ def initialize(group, limit, policy, returnable)
17
+ raise "Invalid Policy" unless POLICIES.include? policy
18
+ @limit = limit
19
+ @group = group
20
+ @policy = policy
21
+ @returnable= returnable
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,78 @@
1
+ module RateLimit
2
+ class WaitExceeded < StandardError
3
+ end
4
+
5
+ class Limiter
6
+ def base_url(local)
7
+ local ? 'http://localhost:8080' : 'http://www.ratelim.it'
8
+ end
9
+
10
+ def initialize(apikey:, account_id:, local: false, debug: false)
11
+ @conn = Faraday.new(:url => self.base_url(local)) do |faraday|
12
+ faraday.request :json # form-encode POST params
13
+ faraday.response :logger if debug
14
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
15
+ end
16
+ @conn.basic_auth(account_id, apikey)
17
+ end
18
+
19
+ def upsert_semaphore(group, limit, policy)
20
+ upsert(LimitDefinition.new(group, limit, policy, true))
21
+ end
22
+
23
+ def upsert_limit(group, limit, policy)
24
+ upsert(LimitDefinition.new(group, limit, policy, false))
25
+ end
26
+
27
+ def check?(group)
28
+ result = acquire(group, 1)
29
+ return result.passed
30
+ end
31
+
32
+ def acquire(group, acquire_amount, allow_partial_response: false)
33
+ result = @conn.post '/api/v1/limitcheck', { acquireAmount: acquire_amount,
34
+ groups: [group],
35
+ allowPartialResponse: allow_partial_response }.to_json
36
+ res =JSON.parse(result.body, object_class: OpenStruct)
37
+ res.amount ||= 0
38
+ res
39
+ end
40
+
41
+ def acquire_or_wait(key:, acquire_amount:, max_wait_secs:, init_backoff: 0)
42
+ start = Time.now
43
+ sleep = init_backoff
44
+ while Time.now - start < max_wait_secs
45
+ sleep(sleep)
46
+ res = acquire(key, acquire_amount)
47
+ if res.passed
48
+ return res
49
+ end
50
+ sleep += rand
51
+ end
52
+ raise RateLimit::WaitExceeded
53
+ end
54
+
55
+
56
+ def return(limit_result)
57
+ @conn.post '/api/v1/limitreturn',
58
+ { enforcedGroup: limit_result.enforcedGroup,
59
+ amount: limit_result.amount }.to_json
60
+ puts result.body
61
+ end
62
+
63
+ private
64
+
65
+ def upsert(limit_definition)
66
+ to_send = { limit: limit_definition.limit,
67
+ group: limit_definition.group,
68
+ policyName: limit_definition.policy,
69
+ returnable: limit_definition.returnable }.to_json
70
+ result= @conn.post '/api/v1/limits', to_send
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ require 'faraday'
77
+ require 'faraday_middleware'
78
+ require 'ratelimit/limit_definition'
@@ -0,0 +1,70 @@
1
+ # Generated by juwelier
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: ratelimit-ruby 0.1.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "ratelimit-ruby"
9
+ s.version = "0.1.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Jeff Dwyer"]
14
+ s.date = "2016-11-18"
15
+ s.description = "rate limit your ruby"
16
+ s.email = "jdwyah@gmail.com"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".ruby-gemset",
24
+ ".ruby-version",
25
+ "Gemfile",
26
+ "Gemfile.lock",
27
+ "LICENSE.txt",
28
+ "README.md",
29
+ "Rakefile",
30
+ "VERSION",
31
+ "lib/ratelimit-ruby.rb",
32
+ "lib/ratelimit/limit_definition.rb",
33
+ "ratelimit-ruby.gemspec"
34
+ ]
35
+ s.homepage = "http://github.com/jdwyah/ratelimit-ruby"
36
+ s.licenses = ["MIT"]
37
+ s.rubygems_version = "2.5.1"
38
+ s.summary = "rate limit your ruby"
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 4
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<faraday>, [">= 0"])
45
+ s.add_runtime_dependency(%q<faraday_middleware>, [">= 0"])
46
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
47
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
49
+ s.add_development_dependency(%q<juwelier>, ["~> 2.1.0"])
50
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<faraday>, [">= 0"])
53
+ s.add_dependency(%q<faraday_middleware>, [">= 0"])
54
+ s.add_dependency(%q<shoulda>, [">= 0"])
55
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
57
+ s.add_dependency(%q<juwelier>, ["~> 2.1.0"])
58
+ s.add_dependency(%q<simplecov>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<faraday>, [">= 0"])
62
+ s.add_dependency(%q<faraday_middleware>, [">= 0"])
63
+ s.add_dependency(%q<shoulda>, [">= 0"])
64
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
65
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
66
+ s.add_dependency(%q<juwelier>, ["~> 2.1.0"])
67
+ s.add_dependency(%q<simplecov>, [">= 0"])
68
+ end
69
+ end
70
+
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ratelimit-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Dwyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: shoulda
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rdoc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: juwelier
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.1.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.1.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: rate limit your ruby
112
+ email: jdwyah@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - LICENSE.txt
117
+ - README.md
118
+ files:
119
+ - ".document"
120
+ - ".ruby-gemset"
121
+ - ".ruby-version"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - VERSION
128
+ - lib/ratelimit-ruby.rb
129
+ - lib/ratelimit/limit_definition.rb
130
+ - ratelimit-ruby.gemspec
131
+ homepage: http://github.com/jdwyah/ratelimit-ruby
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.5.1
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: rate limit your ruby
155
+ test_files: []