excess_flow 1.0.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.
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 ConvertKit, LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'connection_pool'
18
+ require 'redis'
19
+
20
+ require 'excess_flow/constants'
21
+ require 'excess_flow/configuration'
22
+ require 'excess_flow/redis_connection'
23
+
24
+ require 'excess_flow/global_mutex'
25
+ require 'excess_flow/failed_execution'
26
+
27
+ require 'excess_flow/throttle_configuration'
28
+ require 'excess_flow/throttled_executor'
29
+ require 'excess_flow/configuration_error'
30
+
31
+ require 'excess_flow/strategy'
32
+ require 'excess_flow/fixed_window_strategy'
33
+ require 'excess_flow/sliding_window_strategy'
34
+ require 'excess_flow/rate_limited_execution_result'
35
+
36
+ # = ExcessFlow
37
+ #
38
+ # Precise rate limiter with Redis as a backend. For more information on
39
+ # general usage consider consulting README.md file.
40
+ #
41
+ # While interacting with the rate limiter from within your application
42
+ # avoid re-using anything after :: notation as it is part of internal API
43
+ # and is subject to an un-announced breaking change.
44
+ #
45
+ # ExcessFlow provides 5 methods as part of it's public API:
46
+ # * configuration
47
+ # * configure
48
+ # * redis
49
+ # * redis_connection_pool
50
+ # * throttle
51
+ module ExcessFlow
52
+ module_function
53
+
54
+ # Provides access to cache's configuration.
55
+ #
56
+ # @return [Configuration] the object holding configuration values
57
+ def configuration
58
+ @configuration ||= Configuration.new
59
+ end
60
+
61
+ # API to configure cache dynamically during runtime.
62
+ #
63
+ # @yield [configuration] Takes in a block of code of code that is setting
64
+ # or changing configuration values
65
+ #
66
+ # @example Configure during runtime changing redis URL
67
+ # ExcessFlow.configure { |c| c.redis_url = 'foobar' }
68
+ #
69
+ # @return [void]
70
+ def configure
71
+ yield(configuration)
72
+ nil
73
+ end
74
+
75
+ # API to communicate with Redis database backing cache up.
76
+ #
77
+ # @yield [redis]
78
+ #
79
+ # @example Store a value in Redis at given key
80
+ # Store.redis { |r| r.set('meaning_of_life', 42) }
81
+ #
82
+ # @return Returns a result of interaction with Redis
83
+ def redis
84
+ redis_connection_pool.with do |connection|
85
+ yield connection
86
+ end
87
+ end
88
+
89
+ # Accessor to connection pool. Defined on top level so it can be memoized
90
+ # on the topmost level
91
+ #
92
+ # @return [ConnectionPool] ConnectionPool object from connection_pool gem
93
+ def redis_connection_pool
94
+ @redis_connection_pool ||= ExcessFlow::RedisConnection.connection_pool
95
+ end
96
+
97
+ # Executes passed in block of code rate limited using specified strategy
98
+ # and arguments. Different call types can be differentiated and configured
99
+ # using arguments.
100
+ #
101
+ # @param key [String] key to identify your request to limit. Requests that are
102
+ # identified by same key share limits
103
+ # @param limit [Integer] number of requests that can be made in the specified
104
+ # time window
105
+ # @param ttl [Integer] size of window in seconds; how long it will take until
106
+ # the limits are reset
107
+ # @param strategy [Symbol] (optional) specifies which strategy to use to rate
108
+ # limit requests. Optional. Defaults to :fixed_window. Supported strategies
109
+ # are :fixed_window and :sliding_window.
110
+ #
111
+ # @return [ExcessFlow::RateLimitedExecutionResult] Execution result object that
112
+ # will hold result of your execution if it was under the limit. Accessible by
113
+ # calling `result` method. This object has two methods as part of it's public
114
+ # API: `result` (returns either result of execution or ExcessFlow::FailedExecution
115
+ # if limits were breached) and `success?` (returns `true` if request was within
116
+ # limits and else returns `false`).
117
+ def throttle(args, &block)
118
+ ExcessFlow::ThrottledExecutor.select_strategy_and_execute(args, &block)
119
+ end
120
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: excess_flow
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - ConvertKit, LLC
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: connection_pool
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: rake
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: redis
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Hihg precision simple redis based rate limiter.
56
+ email:
57
+ - engineering@convertkit.com
58
+ executables:
59
+ - console
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".circleci/config.yml"
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - ".rubocop.yml"
67
+ - ".travis.yml"
68
+ - CHANGELOG.md
69
+ - CODE_OF_CONDUCT.md
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/console
76
+ - bin/setup
77
+ - excess_flow.gemspec
78
+ - lib/excess_flow.rb
79
+ - lib/excess_flow/configuration.rb
80
+ - lib/excess_flow/configuration_error.rb
81
+ - lib/excess_flow/constants.rb
82
+ - lib/excess_flow/failed_execution.rb
83
+ - lib/excess_flow/fixed_window_strategy.rb
84
+ - lib/excess_flow/global_mutex.rb
85
+ - lib/excess_flow/rate_limited_execution_result.rb
86
+ - lib/excess_flow/redis_connection.rb
87
+ - lib/excess_flow/sliding_window_strategy.rb
88
+ - lib/excess_flow/strategy.rb
89
+ - lib/excess_flow/throttle_configuration.rb
90
+ - lib/excess_flow/throttled_executor.rb
91
+ homepage:
92
+ licenses:
93
+ - Apache License Version 2.0
94
+ metadata:
95
+ source_code_uri: https://github.com/ConvertKit/excess_flow
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubygems_version: 3.0.3
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Redis based rate limiter
115
+ test_files: []