ratelimitcop 1.0.1 → 1.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
2
  SHA256:
3
- metadata.gz: 4e0be667d421af5154e7b84f403f06b8035155e7ee93f38a22bbeff92d022212
4
- data.tar.gz: 350a30c2bee3c06f2b43f8926a34cd4f453a15787c31f74f595b7672aca1446b
3
+ metadata.gz: ac7981e5e89bda694b6285142af637d00500a08d5745e51b9306cbf4729d9049
4
+ data.tar.gz: d047720c407c6e7305f84ec9a3e812f39f964b2ab7038d04734eb8fea31b76e4
5
5
  SHA512:
6
- metadata.gz: 2f604b755935a82868411aac1d95c5f6419c74ec0e047a3f7eee4d6734cf871dba6fc71f0cc89be001f098ea9bdfea27673aaef1fd14cbf6027f83781adef7ba
7
- data.tar.gz: 3fd73c8d828bf2e1573d8611c33f1a532383c758ea5a2651ff6fa2d4b95741a948eea4aae28f739292e34653869d37fe5ad0a3c3a62c4a0b64f64f926366b639
6
+ metadata.gz: c485ff903fdb437b49bb809932298bc6bbd2a12cc5da6bd255096e742ba6429704ca70bb6463b3f3bc724db0e3d7c97852f80c4347b194b0fb754edeaae84346
7
+ data.tar.gz: 5f09f2e566e80108c54fbb3e77c915a7faae8f4c76897e0a7b40adf225165c28bb0e7adf7b616d298660212315e4f83058608f0f4c77388e98da8a736641fd29
@@ -0,0 +1,25 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ ruby-version: ['2.7', '3.0']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
24
+ - name: Run tests
25
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ # v1.1.0
4
+ * [#5](https://github.com/koffeefinance/ratelimitcop/pull/5) Simplify `initialize` method to hide bucket configs in an `options` map - [@mathu97](https://github.com/mathu97).
5
+ * [#5](https://github.com/koffeefinance/ratelimitcop/pull/5) Add `execute` method that calls `add` and blocks if rate limit is exceeded before running user's code block - [@mathu97](https://github.com/mathu97).
6
+ * [#5](https://github.com/koffeefinance/ratelimitcop/pull/5) Add `DummyAPI` class for testing purposes, that can be used to simulate a rate limited API - [@mathu97](https://github.com/mathu97).
7
+
3
8
  # v1.0.1
4
9
  * Renaming of classes to match gem name - [@mathu97](https://github.com/mathu97).
5
10
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ratelimitcop (1.0.1)
4
+ ratelimitcop (1.1.0)
5
5
  redis (~> 4.4)
6
6
  redis-namespace (~> 1.8.1)
7
7
 
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Ratelimitcop
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/ratelimitcop.svg)](https://badge.fury.io/rb/ratelimitcop)
3
+ [![Gem Version](https://badge.fury.io/rb/ratelimitcop.svg)](https://badge.fury.io/rb/ratelimitcop) ![Build Status](https://github.com/koffeefinance/ratelimitcop/actions/workflows/ruby.yml/badge.svg)
4
4
 
5
- Ratelimitcop is a redis backed rate limiter. Appropriate for use cases where in-memory rate limiting would not work (i.e rate limiting across multiple processes, servers, apps, etc).
5
+ Ratelimitcop is a Redis backed rate limiter. Appropriate for use cases where in-memory rate limiting would not work (i.e rate limiting across multiple processes, servers, apps, etc).
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,7 +22,42 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ ### Basic Usage
26
+
27
+ To rate limit calling a block of code, simply initialize `Ratelimitcop` with a `threshold` and `interval`, then pass the block of code to the `execute` method. `threshold` is the maximum number of requests that can be made within a timed `interval`, where `interval` is in seconds. `execute` will automatically block if the execution of your code block will exceed the given rate limit.
28
+
29
+ Note: You need let Ratelimitcop know how it can connect to your Redis instance (or it will default to `localhost`, port 6379, as per the [Redis gem docs](https://www.rubydoc.info/gems/redis#getting-started)). To do this pass your Redis connection config as a parameter when intializing Ratelimitcop. View the [Redis gem docs](https://www.rubydoc.info/gems/redis#getting-started) to see the different ways you can connect Ratelimitcop to your Redis instance.
30
+
31
+ Here is an example of an API client that uses Ratelimitcop to ensure the API's rate limits are not exceeded.
32
+
33
+ ```ruby
34
+ require `iex-ruby-client`
35
+ require `ratelimitcop`
36
+
37
+ class IEXCloudAPIClient
38
+ def initialize
39
+ # rate limit 100 calls per second
40
+ @limiter = Ratelimitcop.new(
41
+ name: 'iex_cloud_api',
42
+ threshold: 100,
43
+ interval: 1,
44
+ redis: {
45
+ url: ENV['REDIS_URL']
46
+ }
47
+ )
48
+
49
+ @client = IEX::Api::Client.new
50
+ end
51
+
52
+ def quote(ticker:)
53
+ # regardless of how this method is called it will block if the rate limit is exceeded before trying to run the code block
54
+ @limiter.execute do
55
+ res = @client.quote(URI.encode(ticker))
56
+ res
57
+ end
58
+ end
59
+ end
60
+ ```
26
61
 
27
62
  ## Development
28
63
 
data/lib/errors.rb ADDED
@@ -0,0 +1 @@
1
+ class InvalidBucketConfigError < StandardError; end
@@ -1,3 +1,3 @@
1
1
  class Ratelimitcop
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
data/lib/ratelimitcop.rb CHANGED
@@ -1,23 +1,25 @@
1
1
  require 'ratelimitcop/version'
2
2
  require 'redis'
3
3
  require 'redis-namespace'
4
+ require_relative 'errors'
4
5
 
5
6
  class Ratelimitcop
6
- attr_reader :name, :threshold, :interval, :time_span, :bucket_span
7
+ attr_reader :name, :threshold, :interval
7
8
 
8
- def initialize(name:, threshold:, interval:, redis_connection: {}, time_span: 600, bucket_span: 5)
9
+ def initialize(name:, threshold:, interval:, redis: {}, options: {})
9
10
  @name = name
10
11
  @threshold = threshold
11
12
  @interval = interval
12
- @time_span = time_span
13
- @bucket_span = bucket_span
13
+ @bucket_interval = options[:bucket_interval] ||= 5
14
+ @bucket_time_span = options[:bucket_time_span] ||= 600
15
+ @bucket_span = options[:bucket_span] ||= @bucket_interval
14
16
 
15
- raise ArgumentError if @interval > @time_span || @interval < @bucket_span
17
+ raise InvalidBucketConfigError if @bucket_interval > @bucket_time_span || @bucket_interval < @bucket_span
16
18
 
17
- @redis ||= Redis::Namespace.new(:limiter, redis: Redis.new(redis_connection))
19
+ @redis ||= Redis::Namespace.new(:limiter, redis: Redis.new(redis))
18
20
 
19
- @all_buckets_count = (@time_span / @bucket_span).floor
20
- @sliding_window_buckets_count = (@interval.to_f / @bucket_span).floor
21
+ @all_buckets_count = (@bucket_time_span / @bucket_span).floor
22
+ @sliding_window_buckets_count = (@bucket_interval.to_f / @bucket_span).floor
21
23
  end
22
24
 
23
25
  def add(count: 1)
@@ -46,6 +48,13 @@ class Ratelimitcop
46
48
  end.map(&:to_i).sum
47
49
  end
48
50
 
51
+ def execute(&block)
52
+ add
53
+ exec_within_threshold do
54
+ block.call
55
+ end
56
+ end
57
+
49
58
  def exec_within_threshold
50
59
  sleep @bucket_span while exceeded?
51
60
  yield
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratelimitcop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathusan Selvarajah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-17 00:00:00.000000000 Z
11
+ date: 2021-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -117,6 +117,7 @@ executables: []
117
117
  extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
+ - ".github/workflows/ruby.yml"
120
121
  - CHANGELOG.md
121
122
  - CODE_OF_CONDUCT.md
122
123
  - Gemfile
@@ -126,6 +127,7 @@ files:
126
127
  - Rakefile
127
128
  - bin/console
128
129
  - bin/setup
130
+ - lib/errors.rb
129
131
  - lib/ratelimitcop.rb
130
132
  - lib/ratelimitcop/version.rb
131
133
  - ratelimitcop.gemspec