pause 0.4.0 → 0.5.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/.github/workflows/rspec.yml +31 -0
- data/.github/workflows/rubocop.yml +31 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +28 -0
- data/.rubocop_todo.yml +192 -0
- data/Gemfile +16 -1
- data/Gemfile.lock +145 -0
- data/Guardfile +7 -6
- data/LICENSE.txt +1 -1
- data/README.md +50 -30
- data/Rakefile +11 -10
- data/bin/spec +14 -0
- data/lib/pause/action.rb +6 -5
- data/lib/pause/analyzer.rb +4 -0
- data/lib/pause/configuration.rb +3 -1
- data/lib/pause/helper/timing.rb +2 -0
- data/lib/pause/logger.rb +12 -5
- data/lib/pause/rate_limited_event.rb +2 -1
- data/lib/pause/redis/adapter.rb +12 -10
- data/lib/pause/redis/sharded_adapter.rb +3 -2
- data/lib/pause/version.rb +3 -1
- data/lib/pause.rb +14 -11
- data/pause.gemspec +14 -17
- data/spec/pause/action_spec.rb +48 -42
- data/spec/pause/analyzer_spec.rb +9 -10
- data/spec/pause/configuration_spec.rb +6 -5
- data/spec/pause/logger_spec.rb +25 -0
- data/spec/pause/pause_spec.rb +6 -4
- data/spec/pause/redis/adapter_spec.rb +54 -35
- data/spec/pause/redis/sharded_adapter_spec.rb +10 -10
- data/spec/spec_helper.rb +11 -7
- metadata +19 -120
- data/.travis.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24edf9a7ae6f6e5556c6dea257d89e8bfa5dd1a4b7115436162758bf259ca36d
|
4
|
+
data.tar.gz: 0f90ae2d8f9dd8678e3e1e8e9dbdbbfd0cbcde8cbf28cf35780924dc3e654b71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b2a54352c815d7c884a64b9953b0ea053b267903d667cceb0503e82756e4459ba766789e1fb85a5f6f079c7d9095aa720f35b464b051da7bc3818058073d91e
|
7
|
+
data.tar.gz: 2a9a41a61e6402516d0f243189af152d170decd6f5e5c5831b2b5d5758d243fe02ab4840e25237b18a557be081819264ed84e70ba1ffa7e524f49a36bd7bae3a
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: RSpec
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
push: { branches: [master] }
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
ruby-version: [3.4.1, 3.3.6, 3.2.6, 3.1.6]
|
13
|
+
env:
|
14
|
+
RUBY_LATEST_VERSION: "3.4.1"
|
15
|
+
RUBY_VERSION: ${{ matrix.ruby-version }}
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v4
|
19
|
+
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
|
25
|
+
- name: Bundle Install
|
26
|
+
run: |
|
27
|
+
bundle check || bundle install -j 4
|
28
|
+
|
29
|
+
- name: Run Rubocop
|
30
|
+
run: |
|
31
|
+
bundle exec rspec --format progress -p1
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Rubocop
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
push: { branches: [master] }
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
ruby-version: [3.4.1, 3.3.6, 3.2.6, 3.1.6]
|
13
|
+
env:
|
14
|
+
RUBY_LATEST_VERSION: "3.4.1"
|
15
|
+
RUBY_VERSION: ${{ matrix.ruby-version }}
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v4
|
19
|
+
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
|
25
|
+
- name: Bundle Install
|
26
|
+
run: |
|
27
|
+
bundle check || bundle install -j 4
|
28
|
+
|
29
|
+
- name: Run Rubocop
|
30
|
+
run: |
|
31
|
+
bundle exec rubocop --parallel --format progress
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
inherit_from: .rubocop_todo.yml
|
6
|
+
|
7
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
8
|
+
# configuration file. It makes it possible to enable/disable
|
9
|
+
# certain cops (checks) and to alter their behavior if they accept
|
10
|
+
# any parameters. The file can be placed either in your home
|
11
|
+
# directory or in some project directory.
|
12
|
+
#
|
13
|
+
# RuboCop will start looking for the configuration file in the directory
|
14
|
+
# where the inspected file is and continue its way up to the root directory.
|
15
|
+
#
|
16
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
17
|
+
#
|
18
|
+
AllCops:
|
19
|
+
NewCops: enable
|
20
|
+
|
21
|
+
RSpec/MultipleMemoizedHelpers:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
RSpec/ExampleLength:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
RSpec/MultipleExpectations:
|
28
|
+
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-02-07 21:04:05 UTC using RuboCop version 1.71.2.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
# Configuration parameters: Severity, Include.
|
11
|
+
# Include: **/*.gemspec
|
12
|
+
Gemspec/RequiredRubyVersion:
|
13
|
+
Exclude:
|
14
|
+
- 'pause.gemspec'
|
15
|
+
|
16
|
+
# Offense count: 9
|
17
|
+
# Configuration parameters: AllowedMethods.
|
18
|
+
# AllowedMethods: enums
|
19
|
+
Lint/ConstantDefinitionInBlock:
|
20
|
+
Exclude:
|
21
|
+
- 'spec/pause/action_spec.rb'
|
22
|
+
- 'spec/pause/analyzer_spec.rb'
|
23
|
+
|
24
|
+
# Offense count: 1
|
25
|
+
# Configuration parameters: AllowedParentClasses.
|
26
|
+
Lint/MissingSuper:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/pause/action.rb'
|
29
|
+
|
30
|
+
# Offense count: 1
|
31
|
+
Lint/StructNewOverride:
|
32
|
+
Exclude:
|
33
|
+
- 'lib/pause.rb'
|
34
|
+
|
35
|
+
# Offense count: 1
|
36
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
37
|
+
Metrics/AbcSize:
|
38
|
+
Max: 33
|
39
|
+
|
40
|
+
# Offense count: 1
|
41
|
+
# Configuration parameters: CountComments, CountAsOne.
|
42
|
+
Metrics/ClassLength:
|
43
|
+
Max: 108
|
44
|
+
|
45
|
+
# Offense count: 1
|
46
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
47
|
+
Metrics/MethodLength:
|
48
|
+
Max: 16
|
49
|
+
|
50
|
+
# Offense count: 1
|
51
|
+
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
52
|
+
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
53
|
+
Naming/MethodParameterName:
|
54
|
+
Exclude:
|
55
|
+
- 'lib/pause/redis/adapter.rb'
|
56
|
+
|
57
|
+
# Offense count: 1
|
58
|
+
RSpec/AnyInstance:
|
59
|
+
Exclude:
|
60
|
+
- 'spec/pause/action_spec.rb'
|
61
|
+
|
62
|
+
# Offense count: 7
|
63
|
+
# Configuration parameters: Prefixes, AllowedPatterns.
|
64
|
+
# Prefixes: when, with, without
|
65
|
+
RSpec/ContextWording:
|
66
|
+
Exclude:
|
67
|
+
- 'spec/pause/action_spec.rb'
|
68
|
+
- 'spec/pause/pause_spec.rb'
|
69
|
+
- 'spec/pause/redis/adapter_spec.rb'
|
70
|
+
|
71
|
+
# Offense count: 1
|
72
|
+
RSpec/DescribeMethod:
|
73
|
+
Exclude:
|
74
|
+
- 'spec/pause/action_spec.rb'
|
75
|
+
|
76
|
+
# Offense count: 15
|
77
|
+
# Configuration parameters: CountAsOne.
|
78
|
+
RSpec/ExampleLength:
|
79
|
+
Max: 14
|
80
|
+
|
81
|
+
# Offense count: 10
|
82
|
+
RSpec/ExpectInHook:
|
83
|
+
Exclude:
|
84
|
+
- 'spec/pause/action_spec.rb'
|
85
|
+
- 'spec/pause/logger_spec.rb'
|
86
|
+
- 'spec/pause/redis/adapter_spec.rb'
|
87
|
+
|
88
|
+
# Offense count: 10
|
89
|
+
RSpec/LeakyConstantDeclaration:
|
90
|
+
Exclude:
|
91
|
+
- 'spec/pause/action_spec.rb'
|
92
|
+
- 'spec/pause/analyzer_spec.rb'
|
93
|
+
|
94
|
+
# Offense count: 10
|
95
|
+
# Configuration parameters: .
|
96
|
+
# SupportedStyles: have_received, receive
|
97
|
+
RSpec/MessageSpies:
|
98
|
+
EnforcedStyle: receive
|
99
|
+
|
100
|
+
# Offense count: 1
|
101
|
+
RSpec/MultipleDescribes:
|
102
|
+
Exclude:
|
103
|
+
- 'spec/pause/action_spec.rb'
|
104
|
+
|
105
|
+
# Offense count: 24
|
106
|
+
RSpec/MultipleExpectations:
|
107
|
+
Max: 6
|
108
|
+
|
109
|
+
# Offense count: 26
|
110
|
+
# Configuration parameters: AllowSubject.
|
111
|
+
RSpec/MultipleMemoizedHelpers:
|
112
|
+
Max: 10
|
113
|
+
|
114
|
+
# Offense count: 14
|
115
|
+
# Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
|
116
|
+
# SupportedStyles: always, named_only
|
117
|
+
RSpec/NamedSubject:
|
118
|
+
Exclude:
|
119
|
+
- 'spec/pause/configuration_spec.rb'
|
120
|
+
|
121
|
+
# Offense count: 2
|
122
|
+
# Configuration parameters: AllowedGroups.
|
123
|
+
RSpec/NestedGroups:
|
124
|
+
Max: 4
|
125
|
+
|
126
|
+
# Offense count: 5
|
127
|
+
# Configuration parameters: AllowedPatterns.
|
128
|
+
# AllowedPatterns: ^expect_, ^assert_
|
129
|
+
RSpec/NoExpectationExample:
|
130
|
+
Exclude:
|
131
|
+
- 'spec/pause/action_spec.rb'
|
132
|
+
- 'spec/pause/logger_spec.rb'
|
133
|
+
- 'spec/pause/redis/adapter_spec.rb'
|
134
|
+
|
135
|
+
# Offense count: 1
|
136
|
+
RSpec/PendingWithoutReason:
|
137
|
+
Exclude:
|
138
|
+
- 'spec/pause/redis/adapter_spec.rb'
|
139
|
+
|
140
|
+
# Offense count: 4
|
141
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
142
|
+
RSpec/ReceiveMessages:
|
143
|
+
Exclude:
|
144
|
+
- 'spec/pause/action_spec.rb'
|
145
|
+
|
146
|
+
# Offense count: 4
|
147
|
+
RSpec/RepeatedDescription:
|
148
|
+
Exclude:
|
149
|
+
- 'spec/pause/action_spec.rb'
|
150
|
+
|
151
|
+
# Offense count: 1
|
152
|
+
# Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
|
153
|
+
# Include: **/*_spec.rb
|
154
|
+
RSpec/SpecFilePathFormat:
|
155
|
+
Exclude:
|
156
|
+
- '**/spec/routing/**/*'
|
157
|
+
- 'spec/pause/configuration_spec.rb'
|
158
|
+
|
159
|
+
# Offense count: 2
|
160
|
+
# This cop supports safe autocorrection (--autocorrect).
|
161
|
+
Rake/Desc:
|
162
|
+
Exclude:
|
163
|
+
- 'Rakefile'
|
164
|
+
|
165
|
+
# Offense count: 6
|
166
|
+
# Configuration parameters: AllowedConstants.
|
167
|
+
Style/Documentation:
|
168
|
+
Exclude:
|
169
|
+
- 'spec/**/*'
|
170
|
+
- 'test/**/*'
|
171
|
+
- 'lib/pause.rb'
|
172
|
+
- 'lib/pause/action.rb'
|
173
|
+
- 'lib/pause/analyzer.rb'
|
174
|
+
- 'lib/pause/configuration.rb'
|
175
|
+
- 'lib/pause/helper/timing.rb'
|
176
|
+
- 'lib/pause/rate_limited_event.rb'
|
177
|
+
|
178
|
+
# Offense count: 1
|
179
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
180
|
+
# Configuration parameters: EnforcedStyle.
|
181
|
+
# SupportedStyles: always, always_true, never
|
182
|
+
Style/FrozenStringLiteralComment:
|
183
|
+
Exclude:
|
184
|
+
- '**/*.arb'
|
185
|
+
- 'spec/pause/action_spec.rb'
|
186
|
+
|
187
|
+
# Offense count: 2
|
188
|
+
# This cop supports safe autocorrection (--autocorrect).
|
189
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
190
|
+
# URISchemes: http, https
|
191
|
+
Layout/LineLength:
|
192
|
+
Max: 307
|
data/Gemfile
CHANGED
@@ -1,7 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# ^syntax detection
|
3
5
|
|
4
6
|
source 'https://rubygems.org'
|
5
7
|
|
8
|
+
group :development, :test do
|
9
|
+
gem 'fakeredis'
|
10
|
+
gem 'guard-rspec'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rspec'
|
13
|
+
gem 'rubocop'
|
14
|
+
gem 'rubocop-rake'
|
15
|
+
gem 'rubocop-rspec'
|
16
|
+
gem 'simplecov'
|
17
|
+
gem 'timecop'
|
18
|
+
gem 'yard'
|
19
|
+
end
|
20
|
+
|
6
21
|
# Specify your gem's dependencies in pause.gemspec
|
7
22
|
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pause (0.5.0)
|
5
|
+
colored2
|
6
|
+
redis
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
ast (2.4.2)
|
12
|
+
coderay (1.1.3)
|
13
|
+
colored2 (4.0.3)
|
14
|
+
diff-lcs (1.5.1)
|
15
|
+
docile (1.4.1)
|
16
|
+
fakeredis (0.9.2)
|
17
|
+
redis (~> 4.8)
|
18
|
+
ffi (1.17.1)
|
19
|
+
ffi (1.17.1-aarch64-linux-gnu)
|
20
|
+
ffi (1.17.1-aarch64-linux-musl)
|
21
|
+
ffi (1.17.1-arm-linux-gnu)
|
22
|
+
ffi (1.17.1-arm-linux-musl)
|
23
|
+
ffi (1.17.1-arm64-darwin)
|
24
|
+
ffi (1.17.1-x86-linux-gnu)
|
25
|
+
ffi (1.17.1-x86-linux-musl)
|
26
|
+
ffi (1.17.1-x86_64-darwin)
|
27
|
+
ffi (1.17.1-x86_64-linux-gnu)
|
28
|
+
ffi (1.17.1-x86_64-linux-musl)
|
29
|
+
formatador (1.1.0)
|
30
|
+
guard (2.19.1)
|
31
|
+
formatador (>= 0.2.4)
|
32
|
+
listen (>= 2.7, < 4.0)
|
33
|
+
logger (~> 1.6)
|
34
|
+
lumberjack (>= 1.0.12, < 2.0)
|
35
|
+
nenv (~> 0.1)
|
36
|
+
notiffany (~> 0.0)
|
37
|
+
ostruct (~> 0.6)
|
38
|
+
pry (>= 0.13.0)
|
39
|
+
shellany (~> 0.0)
|
40
|
+
thor (>= 0.18.1)
|
41
|
+
guard-compat (1.2.1)
|
42
|
+
guard-rspec (4.7.3)
|
43
|
+
guard (~> 2.1)
|
44
|
+
guard-compat (~> 1.1)
|
45
|
+
rspec (>= 2.99.0, < 4.0)
|
46
|
+
json (2.9.1)
|
47
|
+
language_server-protocol (3.17.0.4)
|
48
|
+
listen (3.9.0)
|
49
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
50
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
51
|
+
logger (1.6.5)
|
52
|
+
lumberjack (1.2.10)
|
53
|
+
method_source (1.1.0)
|
54
|
+
nenv (0.3.0)
|
55
|
+
notiffany (0.1.3)
|
56
|
+
nenv (~> 0.1)
|
57
|
+
shellany (~> 0.0)
|
58
|
+
ostruct (0.6.1)
|
59
|
+
parallel (1.26.3)
|
60
|
+
parser (3.3.7.1)
|
61
|
+
ast (~> 2.4.1)
|
62
|
+
racc
|
63
|
+
pry (0.15.2)
|
64
|
+
coderay (~> 1.1)
|
65
|
+
method_source (~> 1.0)
|
66
|
+
racc (1.8.1)
|
67
|
+
rainbow (3.1.1)
|
68
|
+
rake (13.2.1)
|
69
|
+
rb-fsevent (0.11.2)
|
70
|
+
rb-inotify (0.11.1)
|
71
|
+
ffi (~> 1.0)
|
72
|
+
redis (4.8.1)
|
73
|
+
regexp_parser (2.10.0)
|
74
|
+
rspec (3.13.0)
|
75
|
+
rspec-core (~> 3.13.0)
|
76
|
+
rspec-expectations (~> 3.13.0)
|
77
|
+
rspec-mocks (~> 3.13.0)
|
78
|
+
rspec-core (3.13.3)
|
79
|
+
rspec-support (~> 3.13.0)
|
80
|
+
rspec-expectations (3.13.3)
|
81
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
82
|
+
rspec-support (~> 3.13.0)
|
83
|
+
rspec-mocks (3.13.2)
|
84
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
85
|
+
rspec-support (~> 3.13.0)
|
86
|
+
rspec-support (3.13.2)
|
87
|
+
rubocop (1.71.2)
|
88
|
+
json (~> 2.3)
|
89
|
+
language_server-protocol (>= 3.17.0)
|
90
|
+
parallel (~> 1.10)
|
91
|
+
parser (>= 3.3.0.2)
|
92
|
+
rainbow (>= 2.2.2, < 4.0)
|
93
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
94
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
95
|
+
ruby-progressbar (~> 1.7)
|
96
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
97
|
+
rubocop-ast (1.38.0)
|
98
|
+
parser (>= 3.3.1.0)
|
99
|
+
rubocop-rake (0.6.0)
|
100
|
+
rubocop (~> 1.0)
|
101
|
+
rubocop-rspec (3.4.0)
|
102
|
+
rubocop (~> 1.61)
|
103
|
+
ruby-progressbar (1.13.0)
|
104
|
+
shellany (0.0.1)
|
105
|
+
simplecov (0.22.0)
|
106
|
+
docile (~> 1.1)
|
107
|
+
simplecov-html (~> 0.11)
|
108
|
+
simplecov_json_formatter (~> 0.1)
|
109
|
+
simplecov-html (0.13.1)
|
110
|
+
simplecov_json_formatter (0.1.4)
|
111
|
+
thor (1.3.2)
|
112
|
+
timecop (0.9.10)
|
113
|
+
unicode-display_width (3.1.4)
|
114
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
115
|
+
unicode-emoji (4.0.4)
|
116
|
+
yard (0.9.37)
|
117
|
+
|
118
|
+
PLATFORMS
|
119
|
+
aarch64-linux-gnu
|
120
|
+
aarch64-linux-musl
|
121
|
+
arm-linux-gnu
|
122
|
+
arm-linux-musl
|
123
|
+
arm64-darwin
|
124
|
+
ruby
|
125
|
+
x86-linux-gnu
|
126
|
+
x86-linux-musl
|
127
|
+
x86_64-darwin
|
128
|
+
x86_64-linux-gnu
|
129
|
+
x86_64-linux-musl
|
130
|
+
|
131
|
+
DEPENDENCIES
|
132
|
+
fakeredis
|
133
|
+
guard-rspec
|
134
|
+
pause!
|
135
|
+
rake
|
136
|
+
rspec
|
137
|
+
rubocop
|
138
|
+
rubocop-rake
|
139
|
+
rubocop-rspec
|
140
|
+
simplecov
|
141
|
+
timecop
|
142
|
+
yard
|
143
|
+
|
144
|
+
BUNDLED WITH
|
145
|
+
2.6.3
|
data/Guardfile
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# ^syntax detection
|
3
5
|
|
4
6
|
# A sample Guardfile
|
5
7
|
# More info at https://github.com/guard/guard#readme
|
6
8
|
|
7
9
|
guard 'rspec' do
|
8
|
-
watch(
|
9
|
-
watch(%r{^lib/(.+)\.rb$}) {
|
10
|
+
watch(/^spanx\.gemspec/) { 'spec' }
|
11
|
+
watch(%r{^lib/(.+)\.rb$}) { 'spec' }
|
10
12
|
|
11
13
|
watch(%r{^spec/.+_spec\.rb$})
|
12
|
-
watch('spec/spec_helper.rb')
|
13
|
-
watch(%r{spec/support/.*}) {
|
14
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
15
|
+
watch(%r{spec/support/.*}) { 'spec' }
|
14
16
|
end
|
15
|
-
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
# Pause
|
2
1
|
|
3
|
-
[](https://github.com/kigster/pause/actions/workflows/rspec.yml)
|
3
|
+
[](https://github.com/kigster/pause/actions/workflows/rubocop.yml)
|
4
|
+
|
5
|
+
[](https://badge.fury.io/rb/pause)
|
6
|
+
|
7
|
+
[](https://rubygems.org/gems/pause)
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
9
|
+
|
10
|
+
# Pause
|
5
11
|
|
6
12
|
## In a Nutshell
|
7
13
|
|
@@ -49,17 +55,21 @@ Pause.configure do |config|
|
|
49
55
|
config.redis_host = '127.0.0.1'
|
50
56
|
config.redis_port = 6379
|
51
57
|
config.redis_db = 1
|
52
|
-
|
53
|
-
#
|
54
|
-
# Larger blocks require less RAM and CPU, smaller blocks are more
|
55
|
-
# computationally expensive.
|
56
|
-
config.resolution = 600
|
57
|
-
|
58
|
-
# discard all events older than 1 day
|
59
|
-
config.history = 86400
|
58
|
+
config.resolution = 600
|
59
|
+
config.history = 7 * 86400 # discard events older than 7 days
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
+
> NOTE: **resolution** is an setting that's key to understanding how Pause works. It represents the length of time during which similar events are aggregated into a Hash-like object, where the key is the identifier, and the value is the count within that period.
|
64
|
+
>
|
65
|
+
> Because of this,
|
66
|
+
>
|
67
|
+
> * _Larger resolution requires less RAM and CPU and are faster to compute_
|
68
|
+
> * _Smaller resolution is more computationally expensive, but provides higher granularity_.
|
69
|
+
>
|
70
|
+
> The resolution setting must set to the smallest rate-limit period across all of your checks. Below it is set to 10 minutes, meaning that you can use Pause to **rate limit any event to no more than N times within a period of 10 minutes or more.**
|
71
|
+
|
72
|
+
|
63
73
|
#### Define Rate Limited "Action"
|
64
74
|
|
65
75
|
Next we must define the rate limited action based on the specification above. This is how easy it is:
|
@@ -69,13 +79,22 @@ module MyApp
|
|
69
79
|
class UserNotificationLimiter < ::Pause::Action
|
70
80
|
# this is a redis key namespace added to all data in this action
|
71
81
|
scope 'un'
|
72
|
-
|
73
|
-
check period_seconds:
|
74
|
-
|
82
|
+
|
83
|
+
check period_seconds: 120,
|
84
|
+
max_allowed: 1,
|
85
|
+
block_ttl: 240
|
86
|
+
|
87
|
+
check period_seconds: 86400,
|
88
|
+
max_allowed: 3
|
89
|
+
|
90
|
+
check period_seconds: 7 * 86400,
|
91
|
+
max_allowed: 7
|
75
92
|
end
|
76
93
|
end
|
77
94
|
```
|
78
95
|
|
96
|
+
> NOTE: for each check, `block_ttl` defaults to `period_seconds`, and represents the duration of time the action will consider itself as "rate limited" after a particular check reaches the limit. Note, that all actions will automatically leave the "rate limited" state after `block_ttl` seconds have passed.
|
97
|
+
|
79
98
|
#### Perform operation, but only if the user is not rate-limited
|
80
99
|
|
81
100
|
Now we simply instantiate this limiter by passing user ID (any unique identifier works). We can then ask the limiter, `ok?` or `rate_limited?`, or we can use two convenient methods that only execute enclosed block if the described condition is satisfied:
|
@@ -83,17 +102,18 @@ Now we simply instantiate this limiter by passing user ID (any unique identifier
|
|
83
102
|
```ruby
|
84
103
|
class NotificationsWorker
|
85
104
|
def perform(user_id)
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
105
|
+
MyApp::UserNotificationLimiter.new(user_id) do
|
106
|
+
unless_rate_limited do
|
107
|
+
# this block ONLY runs if rate limit is not reached
|
108
|
+
user = User.find(user_id)
|
109
|
+
PushNotifications.new(user).send_push_notification!
|
110
|
+
end
|
111
|
+
|
112
|
+
if_rate_limited do |rate_limit_event|
|
113
|
+
# this block ONLY runs if the action has reached it's rate limit.
|
114
|
+
Rails.logger.info("user #{user.id} has exceeded rate limit: #{rate_limit_event}")
|
115
|
+
end
|
116
|
+
end
|
97
117
|
end
|
98
118
|
end
|
99
119
|
```
|
@@ -301,9 +321,7 @@ Pause.configure do |config|
|
|
301
321
|
end
|
302
322
|
```
|
303
323
|
|
304
|
-
With this configuration, any Pause operation that we know is not supported by Twemproxy will raise
|
305
|
-
`Pause::Redis::OperationNotSupported`. For instance, when sharding we are unable to get a list of all
|
306
|
-
tracked identifiers.
|
324
|
+
With this configuration, any Pause operation that we know is not supported by Twemproxy will raise `Pause::Redis::OperationNotSupported`. For instance, when sharding we are unable to get a list of all tracked identifiers.
|
307
325
|
|
308
326
|
The action block list is implemented as a sorted set, so it should still be usable when sharding.
|
309
327
|
|
@@ -339,8 +357,10 @@ Want to make it better? Cool. Here's how:
|
|
339
357
|
|
340
358
|
## Authors
|
341
359
|
|
342
|
-
This gem was written by Eric Saxby, Atasay Gokkaya and Konstantin Gredeskoul at Wanelo, Inc.
|
360
|
+
* This gem was written by Eric Saxby, Atasay Gokkaya and Konstantin Gredeskoul at Wanelo, Inc.
|
361
|
+
* It's been updated and refreshed by Konstantin Gredeskoul.
|
362
|
+
|
343
363
|
|
344
|
-
Please see the LICENSE.txt file for further details.
|
364
|
+
Please see the [LICENSE.txt](LICENSE.txt) file for further details.
|
345
365
|
|
346
366
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
require 'rspec/core/rake_task'
|
3
5
|
require 'yard'
|
4
6
|
|
5
7
|
RSpec::Core::RakeTask.new(:spec)
|
6
8
|
|
7
|
-
task :
|
9
|
+
task default: %w[spec:unit spec:integration]
|
8
10
|
|
9
11
|
namespace :spec do
|
10
12
|
desc 'Run specs using fakeredis'
|
@@ -25,23 +27,22 @@ def shell(*args)
|
|
25
27
|
end
|
26
28
|
|
27
29
|
task :clean do
|
28
|
-
shell('rm -rf pkg/ tmp/ coverage/ doc/ '
|
30
|
+
shell('rm -rf pkg/ tmp/ coverage/ doc/ ')
|
29
31
|
end
|
30
32
|
|
31
|
-
task :
|
33
|
+
task gem: [:build] do
|
32
34
|
shell('gem install pkg/*')
|
33
35
|
end
|
34
36
|
|
35
|
-
task :
|
37
|
+
task permissions: [:clean] do
|
36
38
|
shell('chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*')
|
37
|
-
shell(
|
39
|
+
shell('find . -type d -exec chmod o+x,g+x {} \\;')
|
38
40
|
end
|
39
41
|
|
40
|
-
task :
|
42
|
+
task build: :permissions
|
41
43
|
|
42
44
|
YARD::Rake::YardocTask.new(:doc) do |t|
|
43
|
-
t.files = %w
|
44
|
-
t.options.unshift('--title','"Pause - Redis-backed Rate Limiter"')
|
45
|
-
t.after = ->
|
45
|
+
t.files = %w[lib/**/*.rb exe/*.rb - README.md LICENSE.txt]
|
46
|
+
t.options.unshift('--title', '"Pause - Redis-backed Rate Limiter"')
|
47
|
+
t.after = -> { exec('open doc/index.html') }
|
46
48
|
end
|
47
|
-
|