rate_limit_control 0.1.1 → 0.1.2

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: 9958b377303639efb40904e16149bbae1989b0e5
4
- data.tar.gz: 170b6744a697ca0032c4765ffa153c5f1d3b20a6
3
+ metadata.gz: c1691c8fdde2802b9942b61e37d63a3bc83c380d
4
+ data.tar.gz: 6c492b7c8aa28e5e2e8930b5e03e28646f157e8c
5
5
  SHA512:
6
- metadata.gz: b67cf3c9bae2ca662720adae630889123f95d9c4773c78f9d4531e92ad6488e327175c7bd373d35fcf36c8f8545a0b7cefd88bb03e1b8649f598cb52882a38ef
7
- data.tar.gz: ec55aedbe3795b2c39a5296e1b390a79ab87683969ee063c8edbcf8173db6f9a8046c997cefc18a2b49c1660a3e7c02d7b4830d03a51c0f545d1f63f27bb58c8
6
+ metadata.gz: ca14669d3e96df8e483f1424cddd56c0fa6c309d0ec78a7246f6b1cedf73097152263d8bcd9f51edf44224e58ce1e2c457abca780ed7fdb55da1d6668f3c83dd
7
+ data.tar.gz: 853a151d1a18edce50535b1990b736bb300fab5358851a5bfa7722e01718195b60f73582abd7c1a7ae260099b56e6fe4aa24867253201c6a713cbfcaf4c2bee2
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ *.gem
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # RateLimitControl
1
+ # Rate limit control
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rate_limit_control`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Take control of the rate limit of your actions. This gem is primarily designed to work with Redis, but you can adapt other key-value databases to work with it. It was inspired by this [post](https://medium.com/@pebneter/fast-and-simple-rate-limiting-with-ruby-on-rails-and-redis-68e76ba38ca4).
6
4
 
7
5
  ## Installation
8
6
 
@@ -22,7 +20,34 @@ Or install it yourself as:
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ Define the configurations of your actions:
24
+
25
+ ```
26
+ action_config = {
27
+ action: 'rate_limit_example',
28
+ id: 'foobar',
29
+ allowed_requests: 5,
30
+ storage: Redis.new,
31
+ timeout: 30,
32
+ }
33
+ ```
34
+
35
+ You need to set your action as a block inside the rate limit control:
36
+ ```
37
+ RateLimitControl.new(action_config) do
38
+ puts "This action will be suspended after the 5th execution"
39
+ end
40
+ ```
41
+
42
+ After the 5th execution, the next action will be blocked until the timeout ends up. All actions with the same configuration will be blocked during this time.
43
+
44
+ ## Action params
45
+
46
+ * **action**: Action name;
47
+ * **id**: Id of the action, the same action could be executed by different requesters;
48
+ * **allowed_requests**: Number of requests allow to be executed during the timeout period;
49
+ * **storage**: Key-value database instance;
50
+ * **timeout**: Time in seconds to unblock actions;
26
51
 
27
52
  ## Development
28
53
 
@@ -1,79 +1,74 @@
1
1
  require "rate_limit_control/version"
2
2
 
3
- module RateLimitControl
4
- class Create
5
- attr_reader :action, :allowed_requests, :session_counter, :storage, :timeout
6
-
7
- def self.call!(configs)
8
- self.new(configs).call
9
- yield
10
- end
11
-
12
- def initialize(configs)
13
- @action = "locked_#{configs[:action]}_#{configs[:id]}_#{Time.now.to_s}"
14
- @allowed_requests = configs[:allowed_requests]
15
- @session_counter = "#{configs[:action]}_#{configs[:id]}"
16
- @storage = configs[:storage]
17
- @timeout = configs[:timeout]
18
- end
3
+ class RateLimitControl
4
+ attr_reader :action, :allowed_requests, :session_counter, :storage, :timeout
5
+
6
+ def initialize(configs)
7
+ @action = "locked_#{configs[:action]}_#{configs[:id]}_#{Time.now.to_s}"
8
+ @allowed_requests = configs[:allowed_requests]
9
+ @session_counter = "#{configs[:action]}_#{configs[:id]}"
10
+ @storage = configs[:storage]
11
+ @timeout = configs[:timeout]
12
+ call
13
+ yield
14
+ end
19
15
 
20
- def call
21
- if session_counter_created?
22
- increment_session_counter
23
- set_action_as_blocked if actions_exceed_the_total_of_allowed?
24
- else
25
- create_session_counter
26
- end
16
+ private
27
17
 
28
- action_blocked_log
29
- while action_blocked?; end
30
- action_executed_log
18
+ def call
19
+ if session_counter_created?
20
+ increment_session_counter
21
+ set_action_as_blocked if actions_exceed_the_total_of_allowed?
22
+ else
23
+ create_session_counter
31
24
  end
32
25
 
33
- private
26
+ action_blocked_log
27
+ while action_blocked?; end
28
+ action_executed_log
29
+ end
34
30
 
35
- def session_counter_created?
36
- storage.get(session_counter).present?
37
- end
31
+ def session_counter_created?
32
+ storage.get(session_counter) != nil
33
+ end
38
34
 
39
- def increment_session_counter
40
- storage.incr(session_counter)
41
- end
35
+ def increment_session_counter
36
+ storage.incr(session_counter)
37
+ end
42
38
 
43
- def set_action_as_blocked
44
- storage.set(action, true)
45
- storage.expire(action, action_timeout)
46
- end
39
+ def set_action_as_blocked
40
+ storage.set(action, true)
41
+ storage.expire(action, action_timeout)
42
+ end
47
43
 
48
- def actions_exceed_the_total_of_allowed?
49
- total_of_actions_executed >= allowed_requests
50
- end
44
+ def actions_exceed_the_total_of_allowed?
45
+ total_of_actions_executed >= allowed_requests
46
+ end
51
47
 
52
- def create_session_counter
53
- storage.set(session_counter, 0)
54
- storage.expire(session_counter, timeout)
55
- end
48
+ def create_session_counter
49
+ storage.set(session_counter, 0)
50
+ storage.expire(session_counter, timeout)
51
+ end
56
52
 
57
- def action_blocked_log
58
- puts "Action is blocked" if action_blocked?
59
- end
53
+ def action_blocked_log
54
+ puts "Action is blocked" if action_blocked?
55
+ end
60
56
 
61
- def action_blocked?
62
- storage.get(action).present?
63
- end
57
+ def action_blocked?
58
+ storage.get(action) != nil
59
+ end
64
60
 
65
- def action_executed_log
66
- puts action
67
- puts "Request executed at #{Time.now.to_s}"
68
- end
61
+ def action_executed_log
62
+ puts action
63
+ puts "Request executed at #{Time.now.to_s}"
64
+ end
69
65
 
70
- def action_timeout
71
- actions_ahead = (total_of_actions_executed / allowed_requests) || 1
72
- actions_ahead * timeout
73
- end
66
+ def action_timeout
67
+ actions_ahead = (total_of_actions_executed / allowed_requests) || 1
68
+ actions_ahead * timeout
69
+ end
74
70
 
75
- def total_of_actions_executed
76
- storage.get(session_counter).to_i
77
- end
71
+ def total_of_actions_executed
72
+ storage.get(session_counter).to_i
78
73
  end
79
74
  end
@@ -1,3 +1,3 @@
1
- module RateLimitControl
2
- VERSION = "0.1.1"
1
+ class RateLimitControl
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rate_limit_control
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Boniatti
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler