pause 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe Pause do
@@ -5,8 +7,8 @@ RSpec.describe Pause do
5
7
  let(:configuration) { Pause::Configuration.new }
6
8
 
7
9
  before do
8
- Pause.adapter = nil
9
- allow(Pause).to receive(:config).and_return(configuration)
10
+ described_class.adapter = nil
11
+ allow(described_class).to receive(:config).and_return(configuration)
10
12
  configuration.configure { |c| c.sharded = sharded }
11
13
  end
12
14
 
@@ -14,7 +16,7 @@ RSpec.describe Pause do
14
16
  let(:sharded) { true }
15
17
 
16
18
  it 'is a ShardedAdapter' do
17
- expect(Pause.adapter).to be_a(Pause::Redis::ShardedAdapter)
19
+ expect(described_class.adapter).to be_a(Pause::Redis::ShardedAdapter)
18
20
  end
19
21
  end
20
22
 
@@ -22,7 +24,7 @@ RSpec.describe Pause do
22
24
  let(:sharded) { false }
23
25
 
24
26
  it 'is an Adapter' do
25
- expect(Pause.adapter).to be_a(Pause::Redis::Adapter)
27
+ expect(described_class.adapter).to be_a(Pause::Redis::Adapter)
26
28
  end
27
29
  end
28
30
  end
@@ -1,59 +1,82 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'date'
3
5
  require 'timecop'
4
6
 
5
7
  describe Pause::Redis::Adapter do
6
-
7
8
  let(:resolution) { 10 }
9
+ let(:adapter) { described_class.new(Pause.config) }
10
+ let(:redis_conn) { adapter.send(:redis) }
8
11
  let(:history) { 60 }
9
12
  let(:configuration) { Pause::Configuration.new }
10
13
 
11
14
  before do
12
15
  allow(Pause).to receive(:config).and_return(configuration)
13
- allow(Pause.config).to receive(:resolution).and_return(resolution)
14
- allow(Pause.config).to receive(:history).and_return(history)
16
+ allow(Pause.config).to receive_messages(resolution: resolution, history: history)
15
17
  redis_conn.flushall
16
18
  end
17
19
 
18
- let(:adapter) { Pause::Redis::Adapter.new(Pause.config) }
19
- let(:redis_conn) { adapter.send(:redis) }
20
-
21
20
  describe '#increment' do
22
21
  let(:scope) { 'blah' }
23
22
  let(:identifier) { '213213' }
24
- let(:tracked_key) { 'i:blah:|213213|' }
23
+ let(:tracked_key) { "i:#{scope}:|#{identifier}|" }
24
+ let(:now) { Time.now.to_i }
25
25
 
26
- it 'should add key to a redis set' do
26
+ it 'adds key to a redis set' do
27
27
  adapter.increment(scope, identifier, Time.now.to_i)
28
- set = redis_conn.zrange(tracked_key, 0, -1, :with_scores => true)
29
- expect(set).to_not be_empty
30
- expect(set.size).to eql(1)
31
- expect(set[0].size).to eql(2)
28
+ set = redis_conn.zrange(tracked_key, 0, -1, with_scores: true)
29
+ expect(set).not_to be_empty
30
+ expect(set.size).to be(1)
31
+ expect(set[0].size).to be(2)
32
+ end
33
+
34
+ describe 'when increment is called' do
35
+ let(:redis_conn_double) { instance_double(Redis) }
36
+
37
+ before do
38
+ allow(adapter).to receive(:with_multi).and_yield(redis_conn_double)
39
+ end
40
+
41
+ it 'calls zincrby on the redis connection' do
42
+ allow(redis_conn_double).to receive(:expire)
43
+ expect(redis_conn_double).to receive(:zincrby)
44
+
45
+ adapter.increment(scope, identifier, Time.now.to_i)
46
+ end
47
+
48
+ it 'calls expire on the redis key' do
49
+ expect(redis_conn_double).to receive(:expire).with(tracked_key, history)
50
+ allow(redis_conn_double).to receive(:zincrby)
51
+
52
+ adapter.increment(scope, identifier, Time.now.to_i)
53
+ end
32
54
  end
33
55
 
34
56
  context 'removing two elements' do
35
57
  let(:to_delete) { 2 }
36
- let(:time) { Time.now }
58
+ let(:period_start) { adapter.period_marker(resolution, now) }
59
+ let(:period_end) { adapter.period_marker(resolution, now + resolution) }
60
+
61
+ around do |example|
62
+ Timecop.freeze(now) { example.run }
63
+ end
64
+
37
65
  before do
38
- adapter
39
- to_delete.times do |t|
40
- expect(redis_conn).to receive(:zrem).with(tracked_key, [adapter.period_marker(resolution, time + t)]).once
41
- end
66
+ redis_conn.flushall
42
67
  adapter.time_blocks_to_keep = 1
68
+ allow(redis_conn).to receive(:zrem).with(tracked_key, [period_start])
69
+ allow(redis_conn).to receive(:zrem).with(tracked_key, [period_start, period_end])
43
70
  end
44
- it 'should remove old elements' do
45
- adapter.increment(scope, identifier, time.to_i)
71
+
72
+ it 'removes old elements' do
73
+ adapter.increment(scope, identifier, now.to_i)
46
74
  to_delete.times do |t|
47
- next_time = time + (adapter.resolution + t + 1)
75
+ next_time = now + (adapter.resolution + t + 1)
48
76
  adapter.increment(scope, identifier, next_time.to_i)
49
77
  end
50
78
  end
51
79
  end
52
-
53
- it 'sets expiry on key' do
54
- expect(redis_conn).to receive(:expire).with(tracked_key, history)
55
- adapter.increment(scope, identifier, Time.now.to_i)
56
- end
57
80
  end
58
81
 
59
82
  describe '#expire_block_list' do
@@ -74,21 +97,18 @@ describe Pause::Redis::Adapter do
74
97
 
75
98
  adapter.expire_block_list(scope)
76
99
 
77
- expect(redis_conn.zscore('b:|a|', blocked_identifier)).not_to be nil
78
- expect(redis_conn.zscore('b:|a|', expired_identifier)).to be nil
100
+ expect(redis_conn.zscore('b:|a|', blocked_identifier)).not_to be_nil
101
+ expect(redis_conn.zscore('b:|a|', expired_identifier)).to be_nil
79
102
  end
80
103
  end
81
104
 
82
- describe '#rate_limit!' do
83
- end
84
-
85
105
  describe '#rate_limited?' do
86
106
  let(:scope) { 'ipn:follow' }
87
107
  let(:identifier) { '123461234' }
88
108
  let(:blocked_key) { "b:#{key}" }
89
- let(:ttl) { 110000 }
109
+ let(:ttl) { 110_000 }
90
110
 
91
- it 'should return true if blocked' do
111
+ it 'returns true if blocked' do
92
112
  adapter.rate_limit!(scope, identifier, ttl)
93
113
  expect(adapter.rate_limited?(scope, identifier)).to be true
94
114
  end
@@ -128,17 +148,16 @@ describe Pause::Redis::Adapter do
128
148
  let(:scope) { 'ipn:follow' }
129
149
  let(:identifier) { '1234' }
130
150
  let(:blocked_key) { "b:|#{scope}|" }
131
- let(:ttl) { 110000 }
151
+ let(:ttl) { 110_000 }
132
152
 
133
153
  it 'saves ip to redis with expiration' do
134
154
  time = Time.now
135
155
  Timecop.freeze time do
136
156
  adapter.rate_limit!(scope, identifier, ttl)
137
157
  end
138
- expect(redis_conn.zscore(blocked_key, identifier)).to_not be nil
158
+ expect(redis_conn.zscore(blocked_key, identifier)).not_to be_nil
139
159
  expect(redis_conn.zscore(blocked_key, identifier)).to eq(time.to_i + ttl)
140
160
  end
141
-
142
161
  end
143
162
  end
144
163
 
@@ -1,21 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'date'
3
5
  require 'timecop'
4
6
 
5
7
  describe Pause::Redis::ShardedAdapter do
6
-
7
8
  let(:resolution) { 10 }
9
+ let(:adapter) { described_class.new(Pause.config) }
8
10
  let(:history) { 60 }
9
11
  let(:configuration) { Pause::Configuration.new }
10
12
 
11
13
  before do
12
14
  allow(Pause).to receive(:config).and_return(configuration)
13
- allow(Pause.config).to receive(:resolution).and_return(resolution)
14
- allow(Pause.config).to receive(:history).and_return(history)
15
+ allow(Pause.config).to receive_messages(resolution: resolution, history: history)
15
16
  end
16
17
 
17
- let(:adapter) { Pause::Redis::ShardedAdapter.new(Pause.config) }
18
-
19
18
  describe '#all_keys' do
20
19
  it 'is not supported' do
21
20
  expect { adapter.all_keys('cake') }.to raise_error(Pause::Redis::OperationNotSupported)
@@ -24,15 +23,16 @@ describe Pause::Redis::ShardedAdapter do
24
23
 
25
24
  describe '#with_multi' do
26
25
  let(:redis) { adapter.send(:redis) }
27
- it 'should not call redis.multi' do
28
- expect(redis).to_not receive(:multi)
29
- expect { adapter.increment(:scope, 123, Time.now) }.to_not raise_error
26
+
27
+ it 'does not call redis.multi' do
28
+ expect(redis).not_to receive(:multi)
29
+ expect { adapter.increment(:scope, 123, Time.now) }.not_to raise_error
30
30
  end
31
31
  end
32
32
 
33
33
  describe '#redis' do
34
- it 'should not use redis db when connecting' do
35
- expect(adapter.send(:redis_connection_opts)).to_not include(:db)
34
+ it 'does not use redis db when connecting' do
35
+ expect(adapter.send(:redis_connection_opts)).not_to include(:db)
36
36
  end
37
37
  end
38
38
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by the `rspec --init` command. Conventionally, all
2
4
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
5
  # Require this file using `require "spec_helper"` to ensure that it is only
@@ -5,28 +7,30 @@
5
7
  #
6
8
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
9
 
8
- require 'pause'
9
10
  require 'fileutils'
10
11
 
12
+ require 'simplecov'
13
+ SimpleCov.start
14
+
15
+ require 'pause'
16
+
11
17
  if ENV['PAUSE_REAL_REDIS']
12
18
  require 'pause/redis/adapter'
13
- puts ; puts "NOTE: Using real Redis-server at #{Pause::Redis::Adapter.redis.inspect}\n\n"
19
+ puts
20
+ puts "NOTE: Using real Redis-server at #{Pause::Redis::Adapter.redis.inspect}\n\n"
14
21
  else
15
22
  require 'fakeredis/rspec'
16
23
  end
17
24
 
18
25
  RSpec.configure do |config|
19
- config.run_all_when_everything_filtered = true
20
- config.filter_run :focus
21
-
22
- rspec_dir = './.spec'.freeze
26
+ rspec_dir = './.spec'
23
27
  FileUtils.mkdir_p(rspec_dir)
24
28
  config.example_status_persistence_file_path = "#{rspec_dir}/results.txt"
25
29
 
26
30
  config.order = 'random'
27
31
 
28
32
  if ENV['PAUSE_REAL_REDIS']
29
- config.before(:example) do
33
+ config.before do
30
34
  Pause::Redis::Adapter.redis.flushdb
31
35
  end
32
36
  end
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pause
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Konstantin Gredeskoul
7
8
  - Atasay Gokkaya
8
9
  - Paul Henry
9
10
  - Eric Saxby
10
- - Konstantin Gredeskoul
11
- autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2018-03-29 00:00:00.000000000 Z
13
+ date: 2025-02-07 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
- name: redis
16
+ name: colored2
18
17
  requirement: !ruby/object:Gem::Requirement
19
18
  requirements:
20
19
  - - ">="
@@ -28,7 +27,7 @@ dependencies:
28
27
  - !ruby/object:Gem::Version
29
28
  version: '0'
30
29
  - !ruby/object:Gem::Dependency
31
- name: hiredis
30
+ name: redis
32
31
  requirement: !ruby/object:Gem::Requirement
33
32
  requirements:
34
33
  - - ">="
@@ -41,126 +40,34 @@ dependencies:
41
40
  - - ">="
42
41
  - !ruby/object:Gem::Version
43
42
  version: '0'
44
- - !ruby/object:Gem::Dependency
45
- name: simplecov
46
- requirement: !ruby/object:Gem::Requirement
47
- requirements:
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: '0'
51
- type: :development
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: '0'
58
- - !ruby/object:Gem::Dependency
59
- name: yard
60
- requirement: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: '0'
65
- type: :development
66
- prerelease: false
67
- version_requirements: !ruby/object:Gem::Requirement
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- version: '0'
72
- - !ruby/object:Gem::Dependency
73
- name: rspec
74
- requirement: !ruby/object:Gem::Requirement
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: '0'
79
- type: :development
80
- prerelease: false
81
- version_requirements: !ruby/object:Gem::Requirement
82
- requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- version: '0'
86
- - !ruby/object:Gem::Dependency
87
- name: fakeredis
88
- requirement: !ruby/object:Gem::Requirement
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: '0'
93
- type: :development
94
- prerelease: false
95
- version_requirements: !ruby/object:Gem::Requirement
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- version: '0'
100
- - !ruby/object:Gem::Dependency
101
- name: guard-rspec
102
- requirement: !ruby/object:Gem::Requirement
103
- requirements:
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- version: '0'
107
- type: :development
108
- prerelease: false
109
- version_requirements: !ruby/object:Gem::Requirement
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: '0'
114
- - !ruby/object:Gem::Dependency
115
- name: timecop
116
- requirement: !ruby/object:Gem::Requirement
117
- requirements:
118
- - - ">="
119
- - !ruby/object:Gem::Version
120
- version: '0'
121
- type: :development
122
- prerelease: false
123
- version_requirements: !ruby/object:Gem::Requirement
124
- requirements:
125
- - - ">="
126
- - !ruby/object:Gem::Version
127
- version: '0'
128
- - !ruby/object:Gem::Dependency
129
- name: rake
130
- requirement: !ruby/object:Gem::Requirement
131
- requirements:
132
- - - ">="
133
- - !ruby/object:Gem::Version
134
- version: '0'
135
- type: :development
136
- prerelease: false
137
- version_requirements: !ruby/object:Gem::Requirement
138
- requirements:
139
- - - ">="
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
43
  description: This gem provides highly flexible and easy to use interface to define
143
44
  rate limit checks, register events as they come, and verify if the rate limit is
144
45
  reached. Multiple checks for the same metric are easily supported. This gem is used
145
46
  at very high scale on several popular web sites.
146
47
  email:
48
+ - kigster@gmail.com
147
49
  - atasay@wanelo.com
148
50
  - paul@wanelo.com
149
51
  - sax@ericsaxby.com
150
- - kigster@gmail.com
151
- executables: []
52
+ executables:
53
+ - spec
152
54
  extensions: []
153
55
  extra_rdoc_files: []
154
56
  files:
57
+ - ".github/workflows/rspec.yml"
58
+ - ".github/workflows/rubocop.yml"
155
59
  - ".gitignore"
156
60
  - ".rspec"
61
+ - ".rubocop.yml"
62
+ - ".rubocop_todo.yml"
157
63
  - ".rvmrc"
158
- - ".travis.yml"
159
64
  - Gemfile
65
+ - Gemfile.lock
160
66
  - Guardfile
161
67
  - LICENSE.txt
162
68
  - README.md
163
69
  - Rakefile
70
+ - bin/spec
164
71
  - lib/pause.rb
165
72
  - lib/pause/action.rb
166
73
  - lib/pause/analyzer.rb
@@ -175,14 +82,15 @@ files:
175
82
  - spec/pause/action_spec.rb
176
83
  - spec/pause/analyzer_spec.rb
177
84
  - spec/pause/configuration_spec.rb
85
+ - spec/pause/logger_spec.rb
178
86
  - spec/pause/pause_spec.rb
179
87
  - spec/pause/redis/adapter_spec.rb
180
88
  - spec/pause/redis/sharded_adapter_spec.rb
181
89
  - spec/spec_helper.rb
182
90
  homepage: https://github.com/kigster/pause
183
91
  licenses: []
184
- metadata: {}
185
- post_install_message:
92
+ metadata:
93
+ rubygems_mfa_required: 'true'
186
94
  rdoc_options: []
187
95
  require_paths:
188
96
  - lib
@@ -197,17 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
105
  - !ruby/object:Gem::Version
198
106
  version: '0'
199
107
  requirements: []
200
- rubyforge_project:
201
- rubygems_version: 2.7.6
202
- signing_key:
108
+ rubygems_version: 3.6.3
203
109
  specification_version: 4
204
110
  summary: Fast, scalable, and flexible real time rate limiting library for distributed
205
111
  Ruby environments backed by Redis.
206
- test_files:
207
- - spec/pause/action_spec.rb
208
- - spec/pause/analyzer_spec.rb
209
- - spec/pause/configuration_spec.rb
210
- - spec/pause/pause_spec.rb
211
- - spec/pause/redis/adapter_spec.rb
212
- - spec/pause/redis/sharded_adapter_spec.rb
213
- - spec/spec_helper.rb
112
+ test_files: []
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3.3
4
- - 2.4.3
5
- - 2.5.0
6
- script: "bundle exec rake || ( sleep 1; bundle exec rspec --only-failures ) "
7
- services:
8
- - redis-server
9
- notifications:
10
- email:
11
- recipients:
12
- - kigster@gmail.com
13
- on_success: never
14
- on_failure: always