kredis 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/lib/kredis/attributes.rb +4 -0
- data/lib/kredis/connections.rb +10 -1
- data/lib/kredis/types/limiter.rb +24 -0
- data/lib/kredis/types.rb +5 -0
- data/lib/kredis/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b979e9602301ecfbea9a89c99cc1b0f3763b26990c9264d7cb767aa258aaac5
|
4
|
+
data.tar.gz: cdd19bdd88263e1cbeae92cf40ad224cc7f84faa3965bd85f4e1f82487964ddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26e3ce8f1580e01c7177ba79caf93b2a3e77276a03e4de30968633e8de675341ab12a16d08f113fe67631bd60c334631d33c6e41bfa70301778e3bf26d64bb70
|
7
|
+
data.tar.gz: 86dd839a25c227d18e04492d6d3a58526be5687fd4dcf20ff94eb127522b51e98b6acbfda4dc0059a56ab22b4a6ff2b4d81b59884636aed03f7ab735fe5b3de7
|
data/README.md
CHANGED
@@ -161,6 +161,20 @@ sleep 0.5.seconds
|
|
161
161
|
true == flag.marked? #=> EXISTS myflag
|
162
162
|
sleep 0.6.seconds
|
163
163
|
false == flag.marked? #=> EXISTS myflag
|
164
|
+
|
165
|
+
limiter = Kredis.limiter "mylimit", limit: 3, expires_in: 5.seconds
|
166
|
+
0 == limiter.value # => GET "limiter"
|
167
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
168
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
169
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
170
|
+
false == limiter.exceeded? # => GET "limiter"
|
171
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
172
|
+
true == limiter.exceeded? # => GET "limiter"
|
173
|
+
sleep 6
|
174
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
175
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
176
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
177
|
+
false == limiter.exceeded? # => GET "limiter"
|
164
178
|
```
|
165
179
|
|
166
180
|
### Models
|
@@ -245,6 +259,8 @@ Additional configurations can be added under `config/redis/*.yml` and referenced
|
|
245
259
|
|
246
260
|
Kredis passes the configuration to `Redis.new` to establish the connection. See the [Redis documentation](https://github.com/redis/redis-rb) for other configuration options.
|
247
261
|
|
262
|
+
If you don't have `config/redis/shared.yml` (or use another named configuration), Kredis will default to look in env for `REDIS_URL`, then fallback to a default URL of `redis://127.0.0.1:6379/0`.
|
263
|
+
|
248
264
|
### Redis support
|
249
265
|
|
250
266
|
Kredis works with Redis server 4.0+, with the [Redis Ruby](https://github.com/redis/redis-rb) client version 4.2+.
|
data/lib/kredis/attributes.rb
CHANGED
@@ -72,6 +72,10 @@ module Kredis::Attributes
|
|
72
72
|
kredis_connection_with __method__, name, key, default: default, config: config, after_change: after_change, expires_in: expires_in
|
73
73
|
end
|
74
74
|
|
75
|
+
def kredis_limiter(name, limit:, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
76
|
+
kredis_connection_with __method__, name, key, limit: limit, config: config, after_change: after_change, expires_in: expires_in
|
77
|
+
end
|
78
|
+
|
75
79
|
def kredis_hash(name, key: nil, default: nil, typed: :string, config: :shared, after_change: nil)
|
76
80
|
kredis_connection_with __method__, name, key, default: default, typed: typed, config: config, after_change: after_change
|
77
81
|
end
|
data/lib/kredis/connections.rb
CHANGED
@@ -3,13 +3,22 @@
|
|
3
3
|
require "redis"
|
4
4
|
|
5
5
|
module Kredis::Connections
|
6
|
+
DEFAULT_REDIS_URL = "redis://127.0.0.1:6379/0"
|
7
|
+
DEFAULT_REDIS_TIMEOUT = 1
|
8
|
+
|
6
9
|
mattr_accessor :connections, default: Hash.new
|
7
10
|
mattr_accessor :configurator
|
8
11
|
mattr_accessor :connector, default: ->(config) { Redis.new(config) }
|
9
12
|
|
10
13
|
def configured_for(name)
|
11
14
|
connections[name] ||= Kredis.instrument :meta, message: "Connected to #{name}" do
|
12
|
-
|
15
|
+
if configurator.root.join("config/redis/#{name}.yml").exist?
|
16
|
+
connector.call configurator.config_for("redis/#{name}")
|
17
|
+
elsif name == :shared
|
18
|
+
Redis.new url: ENV.fetch("REDIS_URL", DEFAULT_REDIS_URL), timeout: DEFAULT_REDIS_TIMEOUT
|
19
|
+
else
|
20
|
+
raise "No configuration found for #{name}"
|
21
|
+
end
|
13
22
|
end
|
14
23
|
end
|
15
24
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A limiter is a specialized form of a counter that can be checked whether it has been exceeded and is provided fail safe. This means it can be used to guard login screens from brute force attacks without denying access in case Redis is offline.
|
4
|
+
#
|
5
|
+
# It will usually be used as an expiring limiter. Note that the limiter expires in total after the `expires_in` time used upon the first poke.
|
6
|
+
#
|
7
|
+
# It offers no guarentee that you can't poke yourself above the limit. You're responsible for checking `#exceeded?` yourself first, and this may produce a race condition. So only use this when the exact number of pokes is not critical.
|
8
|
+
class Kredis::Types::Limiter < Kredis::Types::Counter
|
9
|
+
class LimitExceeded < StandardError; end
|
10
|
+
|
11
|
+
attr_accessor :limit
|
12
|
+
|
13
|
+
def poke
|
14
|
+
failsafe returning: true do
|
15
|
+
increment
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def exceeded?
|
20
|
+
failsafe returning: false do
|
21
|
+
value >= limit
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/kredis/types.rb
CHANGED
@@ -85,6 +85,10 @@ module Kredis::Types
|
|
85
85
|
type_from(Slots, config, key, after_change: after_change, available: available)
|
86
86
|
end
|
87
87
|
|
88
|
+
def limiter(key, limit:, expires_in: nil, config: :shared, after_change: nil)
|
89
|
+
type_from(Limiter, config, key, after_change: after_change, expires_in: expires_in, limit: limit)
|
90
|
+
end
|
91
|
+
|
88
92
|
private
|
89
93
|
def type_from(type_klass, config, key, after_change: nil, **options)
|
90
94
|
type_klass.new(configured_for(config), namespaced_key(key), **options).then do |type|
|
@@ -107,3 +111,4 @@ require "kredis/types/unique_list"
|
|
107
111
|
require "kredis/types/set"
|
108
112
|
require "kredis/types/ordered_set"
|
109
113
|
require "kredis/types/slots"
|
114
|
+
require "kredis/types/limiter"
|
data/lib/kredis/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-12-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- lib/kredis/types/enum.rb
|
103
103
|
- lib/kredis/types/flag.rb
|
104
104
|
- lib/kredis/types/hash.rb
|
105
|
+
- lib/kredis/types/limiter.rb
|
105
106
|
- lib/kredis/types/list.rb
|
106
107
|
- lib/kredis/types/ordered_set.rb
|
107
108
|
- lib/kredis/types/proxy.rb
|
@@ -132,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
133
|
- !ruby/object:Gem::Version
|
133
134
|
version: '0'
|
134
135
|
requirements: []
|
135
|
-
rubygems_version: 3.4.
|
136
|
+
rubygems_version: 3.4.14
|
136
137
|
signing_key:
|
137
138
|
specification_version: 4
|
138
139
|
summary: Higher-level data structures built on Redis.
|