kredis 1.6.1 → 1.8.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/MIT-LICENSE +2 -2
- data/README.md +19 -1
- data/lib/kredis/attributes.rb +4 -0
- data/lib/kredis/namespace.rb +21 -4
- data/lib/kredis/railtie.rb +1 -1
- data/lib/kredis/types/hash.rb +1 -1
- data/lib/kredis/types/limiter.rb +24 -0
- data/lib/kredis/types/set.rb +5 -2
- data/lib/kredis/types.rb +5 -0
- data/lib/kredis/version.rb +1 -1
- metadata +4 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7b578a8b9d0b956e519c324d7ba9dd6036124637801366d9f1a2719a7d340d5
|
4
|
+
data.tar.gz: a4bc7d1a74540a7bd41691105833123bffd27ff32f07b01ce82986820d6068e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ca284918aa9079b5265f1603a9ff33c7fe6f562b4cf76a97ce571542a7dccb9265d2d94441b578570729e415d0ea1adf29786612a31635660cebe82917172df
|
7
|
+
data.tar.gz: 569e06a45f6696800372a6f11a953e12267faf009596767366a860c0f6f691c40668d5a0e94ea7cd0c9bf09370870bca209a3e9081d8f0489be79fce64864ae1
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2020
|
1
|
+
Copyright (c) 2020-2025 37signals LLC
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -48,11 +48,13 @@ There are data structures for counters, enums, flags, lists, unique lists, sets,
|
|
48
48
|
list = Kredis.list "mylist"
|
49
49
|
list << "hello world!" # => RPUSH mylist "hello world!"
|
50
50
|
[ "hello world!" ] == list.elements # => LRANGE mylist 0, -1
|
51
|
+
list.clear # => DEL mylist
|
51
52
|
|
52
53
|
integer_list = Kredis.list "myintegerlist", typed: :integer, default: [ 1, 2, 3 ] # => EXISTS? myintegerlist, RPUSH myintegerlist "1" "2" "3"
|
53
54
|
integer_list.append([ 4, 5, 6 ]) # => RPUSH myintegerlist "4" "5" "6"
|
54
55
|
integer_list << 7 # => RPUSH myintegerlist "7"
|
55
56
|
[ 1, 2, 3, 4, 5, 6, 7 ] == integer_list.elements # => LRANGE myintegerlist 0 -1
|
57
|
+
integer_list.clear # => DEL myintegerlist
|
56
58
|
|
57
59
|
unique_list = Kredis.unique_list "myuniquelist"
|
58
60
|
unique_list.append(%w[ 2 3 4 ]) # => LREM myuniquelist 0, "2" + LREM myuniquelist 0, "3" + LREM myuniquelist 0, "4" + RPUSH myuniquelist "2", "3", "4"
|
@@ -61,6 +63,7 @@ unique_list.append([])
|
|
61
63
|
unique_list << "5" # => LREM myuniquelist 0, "5" + RPUSH myuniquelist "5"
|
62
64
|
unique_list.remove(3) # => LREM myuniquelist 0, "3"
|
63
65
|
[ "4", "2", "1", "5" ] == unique_list.elements # => LRANGE myuniquelist 0, -1
|
66
|
+
unique_list.clear # => DEL myuniquelist
|
64
67
|
|
65
68
|
ordered_set = Kredis.ordered_set "myorderedset"
|
66
69
|
ordered_set.append(%w[ 2 3 4 ]) # => ZADD myorderedset 1646131025.4953232 2 1646131025.495326 3 1646131025.4953272 4
|
@@ -75,6 +78,7 @@ set.add(DateTime.tomorrow, DateTime.yesterday) # => SADD myset "2021-0
|
|
75
78
|
set << DateTime.tomorrow # => SADD myset "2021-02-03 00:00:00 +0100"
|
76
79
|
2 == set.size # => SCARD myset
|
77
80
|
[ DateTime.tomorrow, DateTime.yesterday ] == set.members # => SMEMBERS myset
|
81
|
+
set.clear # => DEL myset
|
78
82
|
|
79
83
|
hash = Kredis.hash "myhash"
|
80
84
|
hash.update("key" => "value", "key2" => "value2") # => HSET myhash "key", "value", "key2", "value2"
|
@@ -102,6 +106,7 @@ counter.increment by: 2 # => SET mycounter 0 EX 5 NX + INCRBY "mycounter
|
|
102
106
|
2 == counter.value # => GET "mycounter"
|
103
107
|
sleep 6.seconds
|
104
108
|
0 == counter.value # => GET "mycounter"
|
109
|
+
counter.reset # => DEL mycounter
|
105
110
|
|
106
111
|
cycle = Kredis.cycle "mycycle", values: %i[ one two three ]
|
107
112
|
:one == cycle.value # => GET mycycle
|
@@ -111,6 +116,7 @@ cycle.next # => GET mycycle + SET mycycle 2
|
|
111
116
|
:three == cycle.value # => GET mycycle
|
112
117
|
cycle.next # => GET mycycle + SET mycycle 0
|
113
118
|
:one == cycle.value # => GET mycycle
|
119
|
+
cycle.reset # => DEL mycycle
|
114
120
|
|
115
121
|
enum = Kredis.enum "myenum", values: %w[ one two three ], default: "one"
|
116
122
|
"one" == enum.value # => GET myenum
|
@@ -161,6 +167,18 @@ sleep 0.5.seconds
|
|
161
167
|
true == flag.marked? #=> EXISTS myflag
|
162
168
|
sleep 0.6.seconds
|
163
169
|
false == flag.marked? #=> EXISTS myflag
|
170
|
+
|
171
|
+
limiter = Kredis.limiter "mylimit", limit: 3, expires_in: 5.seconds
|
172
|
+
0 == limiter.value # => GET "limiter"
|
173
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
174
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
175
|
+
false == limiter.exceeded? # => GET "limiter"
|
176
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
177
|
+
true == limiter.exceeded? # => GET "limiter"
|
178
|
+
sleep 6
|
179
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
180
|
+
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
|
181
|
+
false == limiter.exceeded? # => GET "limiter"
|
164
182
|
```
|
165
183
|
|
166
184
|
### Models
|
@@ -249,7 +267,7 @@ If you don't have `config/redis/shared.yml` (or use another named configuration)
|
|
249
267
|
|
250
268
|
### Redis support
|
251
269
|
|
252
|
-
Kredis works with Redis server 4.0+, with the [Redis Ruby](https://github.com/redis/redis-rb) client version 4.2+.
|
270
|
+
Kredis works with Redis server 4.0+, with the [Redis Ruby](https://github.com/redis/redis-rb) client version 4.2+. Redis Cluster is not supported.
|
253
271
|
|
254
272
|
### Setting SSL options on Redis Connections
|
255
273
|
|
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/namespace.rb
CHANGED
@@ -1,14 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Kredis::Namespace
|
4
|
-
|
5
|
-
Thread.current[:kredis_namespace] = namespace
|
6
|
-
end
|
4
|
+
attr_accessor :global_namespace
|
7
5
|
|
8
6
|
def namespace
|
9
|
-
|
7
|
+
if global_namespace
|
8
|
+
if value = thread_namespace
|
9
|
+
"#{global_namespace}:#{value}"
|
10
|
+
else
|
11
|
+
global_namespace
|
12
|
+
end
|
13
|
+
else
|
14
|
+
thread_namespace
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def thread_namespace
|
19
|
+
Thread.current[:kredis_thread_namespace]
|
10
20
|
end
|
11
21
|
|
22
|
+
def thread_namespace=(value)
|
23
|
+
Thread.current[:kredis_thread_namespace] = value
|
24
|
+
end
|
25
|
+
|
26
|
+
# Backward compatibility
|
27
|
+
alias_method :namespace=, :thread_namespace=
|
28
|
+
|
12
29
|
def namespaced_key(key)
|
13
30
|
namespace ? "#{namespace}:#{key}" : key
|
14
31
|
end
|
data/lib/kredis/railtie.rb
CHANGED
@@ -5,7 +5,7 @@ class Kredis::Railtie < ::Rails::Railtie
|
|
5
5
|
|
6
6
|
initializer "kredis.testing" do
|
7
7
|
ActiveSupport.on_load(:active_support_test_case) do
|
8
|
-
parallelize_setup { |worker| Kredis.
|
8
|
+
parallelize_setup { |worker| Kredis.global_namespace = [ Kredis.global_namespace, :test, worker ].compact.join("-") }
|
9
9
|
teardown { Kredis.clear_all }
|
10
10
|
end
|
11
11
|
end
|
data/lib/kredis/types/hash.rb
CHANGED
@@ -18,7 +18,7 @@ class Kredis::Types::Hash < Kredis::Types::Proxying
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def update(**entries)
|
21
|
-
hset entries.transform_values { |val| type_to_string(val, typed) } if entries.flatten.any?
|
21
|
+
hset entries.transform_values { |val| type_to_string(val, typed) }.compact if entries.flatten.any?
|
22
22
|
end
|
23
23
|
|
24
24
|
def values_at(*keys)
|
@@ -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/set.rb
CHANGED
@@ -3,10 +3,13 @@
|
|
3
3
|
class Kredis::Types::Set < Kredis::Types::Proxying
|
4
4
|
prepend Kredis::DefaultValues
|
5
5
|
|
6
|
-
proxying :smembers, :sadd, :srem, :multi, :del, :sismember, :scard, :spop, :exists?, :srandmember
|
6
|
+
proxying :smembers, :sadd, :srem, :multi, :del, :sismember, :scard, :spop, :exists?, :srandmember, :smove
|
7
7
|
|
8
8
|
attr_accessor :typed
|
9
|
-
|
9
|
+
def move(set, member)
|
10
|
+
destination = set.respond_to?(:key) ? set.key : set
|
11
|
+
smove(destination, member)
|
12
|
+
end
|
10
13
|
def members
|
11
14
|
strings_to_types(smembers || [], typed).sort
|
12
15
|
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,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
8
8
|
- David Heinemeier Hansson
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activesupport
|
@@ -73,7 +72,6 @@ dependencies:
|
|
73
72
|
- - ">="
|
74
73
|
- !ruby/object:Gem::Version
|
75
74
|
version: 6.0.0
|
76
|
-
description:
|
77
75
|
email: david@hey.com
|
78
76
|
executables: []
|
79
77
|
extensions: []
|
@@ -102,6 +100,7 @@ files:
|
|
102
100
|
- lib/kredis/types/enum.rb
|
103
101
|
- lib/kredis/types/flag.rb
|
104
102
|
- lib/kredis/types/hash.rb
|
103
|
+
- lib/kredis/types/limiter.rb
|
105
104
|
- lib/kredis/types/list.rb
|
106
105
|
- lib/kredis/types/ordered_set.rb
|
107
106
|
- lib/kredis/types/proxy.rb
|
@@ -117,7 +116,6 @@ homepage: https://github.com/rails/kredis
|
|
117
116
|
licenses:
|
118
117
|
- MIT
|
119
118
|
metadata: {}
|
120
|
-
post_install_message:
|
121
119
|
rdoc_options: []
|
122
120
|
require_paths:
|
123
121
|
- lib
|
@@ -132,8 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
130
|
- !ruby/object:Gem::Version
|
133
131
|
version: '0'
|
134
132
|
requirements: []
|
135
|
-
rubygems_version: 3.
|
136
|
-
signing_key:
|
133
|
+
rubygems_version: 3.6.7
|
137
134
|
specification_version: 4
|
138
135
|
summary: Higher-level data structures built on Redis.
|
139
136
|
test_files: []
|