EasyThrottle 0.0.1 → 0.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 +4 -4
- data/.gitignore +3 -0
- data/Gemfile +5 -0
- data/easy_throttle.gemspec +20 -0
- data/lib/easy_throttle/configuration.rb +24 -0
- data/lib/easy_throttle/easy_throttle.rb +22 -0
- data/lib/easy_throttle/error.rb +9 -0
- data/lib/easy_throttle/version.rb +5 -0
- data/lib/{throttler.rb → easy_throttle.rb} +4 -9
- data/test/test_easy_throttle.rb +40 -0
- metadata +19 -10
- data/lib/config.yml +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9332a078cd5d2315222eb5c21cb7b962eab5675fc37dcb3b735a363965df105e
|
|
4
|
+
data.tar.gz: 68bb1a74c62fb3c6a7fbaf9e943c7b1bca0c825c39c6a15b85ddd2c8349f3692
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42612634bbab62c840994e2f5b4593211cce22d19c69efe1ded7e6ed2b82a21e6209b725b1db71852a3175298824899dee5af6d6825de64ec34cb3c109346239
|
|
7
|
+
data.tar.gz: 8395d6b5e34d5db37b530a5805fb8696c88fb9e13600aa9d6537570c24ea601687446f30af4986ee24b09df37396852fd71dc4c0a4dfdc8b7b93f6874d71aa18
|
data/.gitignore
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
|
3
|
+
require 'easy_throttle/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'EasyThrottle'
|
|
7
|
+
s.version = EasyThrottle::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ["Damian Szalbierz"]
|
|
10
|
+
s.email = ['szalbierz.d.k@gmail.com']
|
|
11
|
+
s.homepage = 'https://github.com/Szalbik/easy_throttle'
|
|
12
|
+
s.summary = "Allows you to throttle requests to an API."
|
|
13
|
+
s.licenses = ['MIT']
|
|
14
|
+
|
|
15
|
+
s.add_runtime_dependency 'redis', '~> 4.0'
|
|
16
|
+
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
+
s.require_paths = ['lib']
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EasyThrottle
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :interval, :limit, :burst, :errors, :limits
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@interval = 60
|
|
9
|
+
@limit = 1
|
|
10
|
+
@burst = 20
|
|
11
|
+
@errors = [AmzSpApi::ApiError]
|
|
12
|
+
@limits = {}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def add_error(error)
|
|
16
|
+
@errors << error
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Options example: { interval: 10, limit: 1, burst: 1 }
|
|
20
|
+
def add_limit(endpoint, options = {})
|
|
21
|
+
@limits[endpoint] = options
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EasyThrottle
|
|
4
|
+
class << self
|
|
5
|
+
# Instantiate the Configuration singleton
|
|
6
|
+
# or return it. Remember that the instance
|
|
7
|
+
# has attribute readers so that we can access
|
|
8
|
+
# the configured values
|
|
9
|
+
def configuration
|
|
10
|
+
@configuration ||= Configuration.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# This is the configure block definition.
|
|
14
|
+
# The configuration method will return the
|
|
15
|
+
# Configuration singleton, which is then yielded
|
|
16
|
+
# to the configure block. Then it's just a matter
|
|
17
|
+
# of using the attribute accessors we previously defined
|
|
18
|
+
def configure
|
|
19
|
+
yield(configuration)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'yaml'
|
|
4
3
|
require 'redis'
|
|
5
4
|
|
|
6
|
-
class
|
|
5
|
+
class EasyThrottle
|
|
7
6
|
DEFAULT_OPTIONS = { interval: 60, limit: 1, burst: 20 }.freeze
|
|
8
|
-
LIMITS = {
|
|
9
|
-
# 'endpointName' => { interval: 10, limit: 1, burst: 1 },
|
|
10
|
-
}.freeze
|
|
11
7
|
|
|
12
8
|
def self.with_throttling(endpoint, prefix, options = DEFAULT_OPTIONS, &block)
|
|
13
9
|
new(endpoint, prefix, options).with_throttling { block.call }
|
|
14
10
|
end
|
|
15
11
|
|
|
16
12
|
def initialize(endpoint, prefix, options = DEFAULT_OPTIONS)
|
|
17
|
-
@config = YAML.load_file('lib/config.yml')
|
|
18
13
|
@endpoint = endpoint
|
|
19
14
|
@prefix = prefix
|
|
20
15
|
@redis = Redis.new
|
|
21
|
-
@options =
|
|
16
|
+
@options = EasyThrottle.configuration.limits.fetch(endpoint, options)
|
|
22
17
|
end
|
|
23
18
|
|
|
24
19
|
def with_throttling(&block)
|
|
@@ -34,7 +29,7 @@ class Throttler
|
|
|
34
29
|
end
|
|
35
30
|
end
|
|
36
31
|
result
|
|
37
|
-
rescue
|
|
32
|
+
rescue EasyThrottle.configuration.errors => e
|
|
38
33
|
if e.code == 429
|
|
39
34
|
extend_key_duration
|
|
40
35
|
retry
|
|
@@ -46,7 +41,7 @@ class Throttler
|
|
|
46
41
|
retry
|
|
47
42
|
end
|
|
48
43
|
|
|
49
|
-
raise
|
|
44
|
+
raise EasyThrottle::Error.new(msg: e.message, error: e)
|
|
50
45
|
end
|
|
51
46
|
|
|
52
47
|
def pool
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require_relative '../lib/throttler'
|
|
5
|
+
|
|
6
|
+
class ThrottlerTest < Minitest::Test
|
|
7
|
+
def setup
|
|
8
|
+
@endpoint = 'getItemOffers'
|
|
9
|
+
@prefix = 'US'
|
|
10
|
+
@redis = Minitest::Mock.new
|
|
11
|
+
@options = Throttler::DEFAULT_OPTIONS
|
|
12
|
+
@burst_key = "#{@prefix}:#{@endpoint}:burst"
|
|
13
|
+
@subject = Throttler.new(@endpoint, @prefix, @options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_initialize
|
|
17
|
+
assert_equal @endpoint, @subject.instance_variable_get(:@endpoint)
|
|
18
|
+
assert_equal @prefix, @subject.instance_variable_get(:@prefix)
|
|
19
|
+
assert_equal @options, @subject.instance_variable_get(:@options)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_with_throttling
|
|
23
|
+
block = proc { 'result' }
|
|
24
|
+
@redis.expect(:pttl, 0)
|
|
25
|
+
@redis.expect(:psetex, true)
|
|
26
|
+
assert_equal 'result', @subject.with_throttling(&block)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_with_throttling_when_api_error_with_code_429_occurs
|
|
30
|
+
block = proc { raise StandardError.new(code: 429) }
|
|
31
|
+
assert_raises(StandardError) { @subject.with_throttling(&block) }
|
|
32
|
+
assert_mock @redis
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_with_throttling_when_api_error_with_code_500_occurs
|
|
36
|
+
block = proc { raise StandardError.new(code: 500) }
|
|
37
|
+
assert_raises(StandardError) { @subject.with_throttling(&block) }
|
|
38
|
+
assert_mock @redis
|
|
39
|
+
end
|
|
40
|
+
end
|
metadata
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: EasyThrottle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Damian Szalbierz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-03-
|
|
11
|
+
date: 2024-03-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '4.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
26
|
version: '4.0'
|
|
27
27
|
description:
|
|
28
|
-
email:
|
|
28
|
+
email:
|
|
29
|
+
- szalbierz.d.k@gmail.com
|
|
29
30
|
executables: []
|
|
30
31
|
extensions: []
|
|
31
32
|
extra_rdoc_files: []
|
|
32
33
|
files:
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
|
|
34
|
+
- ".gitignore"
|
|
35
|
+
- Gemfile
|
|
36
|
+
- easy_throttle.gemspec
|
|
37
|
+
- lib/easy_throttle.rb
|
|
38
|
+
- lib/easy_throttle/configuration.rb
|
|
39
|
+
- lib/easy_throttle/easy_throttle.rb
|
|
40
|
+
- lib/easy_throttle/error.rb
|
|
41
|
+
- lib/easy_throttle/version.rb
|
|
42
|
+
- test/test_easy_throttle.rb
|
|
43
|
+
homepage: https://github.com/Szalbik/easy_throttle
|
|
36
44
|
licenses:
|
|
37
45
|
- MIT
|
|
38
46
|
metadata: {}
|
|
@@ -51,8 +59,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
51
59
|
- !ruby/object:Gem::Version
|
|
52
60
|
version: '0'
|
|
53
61
|
requirements: []
|
|
54
|
-
rubygems_version: 3.
|
|
62
|
+
rubygems_version: 3.3.7
|
|
55
63
|
signing_key:
|
|
56
64
|
specification_version: 4
|
|
57
65
|
summary: Allows you to throttle requests to an API.
|
|
58
|
-
test_files:
|
|
66
|
+
test_files:
|
|
67
|
+
- test/test_easy_throttle.rb
|
data/lib/config.yml
DELETED