kredis 0.2.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of kredis might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +137 -51
- data/lib/kredis/attributes.rb +51 -25
- data/lib/kredis/connections.rb +13 -4
- data/lib/kredis/log_subscriber.rb +22 -0
- data/lib/kredis/migration.rb +6 -4
- data/lib/kredis/railtie.rb +20 -24
- data/lib/kredis/type/datetime.rb +15 -0
- data/lib/kredis/type/json.rb +19 -0
- data/lib/kredis/type_casting.rb +24 -34
- data/lib/kredis/types/callbacks_proxy.rb +31 -0
- data/lib/kredis/types/counter.rb +5 -1
- data/lib/kredis/types/cycle.rb +13 -0
- data/lib/kredis/types/enum.rb +2 -0
- data/lib/kredis/types/hash.rb +44 -0
- data/lib/kredis/types/list.rb +3 -3
- data/lib/kredis/types/proxy.rb +5 -5
- data/lib/kredis/types/scalar.rb +18 -4
- data/lib/kredis/types/set.rb +3 -3
- data/lib/kredis/types.rb +53 -34
- data/lib/kredis/version.rb +1 -1
- data/lib/kredis.rb +14 -4
- metadata +28 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c7614f548dde6852fd7e654215ba56f103fec5ac7ad6ae477fe2621f3b9964a
|
4
|
+
data.tar.gz: a023026462ec8a09f1e26550ce56abaeb95b1f0582665787cda48ef91e9048d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3755bc5be9370676ac5b2a4a6100a26d0ed09b1248d87114911020ec1b9eb6ab094d25ec6686478069add02197d5188f59edcab04ccc69fed9bb80d1db9966f
|
7
|
+
data.tar.gz: 6f97f9ad814700b69b5663697add1f4b2d3468d05752c053c883ca0e8d93703b91af06f6a2593ee6ba79835435663c51c78cd17df32dafb1d7efc666150e77f6
|
data/README.md
CHANGED
@@ -20,6 +20,23 @@ integer = Kredis.integer "myinteger"
|
|
20
20
|
integer.value = 5 # => SET myinteger "5"
|
21
21
|
5 == integer.value # => GET myinteger
|
22
22
|
|
23
|
+
decimal = Kredis.decimal "mydecimal" # accuracy!
|
24
|
+
decimal.value = "%.47f" % (1.0/10) # => SET mydecimal "0.10000000000000000555111512312578270211815834045"
|
25
|
+
BigDecimal("0.10000000000000000555111512312578270211815834045e0") == decimal.value # => GET mydecimal
|
26
|
+
|
27
|
+
float = Kredis.float "myfloat" # speed!
|
28
|
+
float.value = 1.0/10 # => SET myfloat "0.1"
|
29
|
+
0.1 == float.value # => GET myfloat
|
30
|
+
|
31
|
+
boolean = Kredis.boolean "myboolean"
|
32
|
+
boolean.value = true # => SET myboolean "t"
|
33
|
+
true == boolean.value # => GET myboolean
|
34
|
+
|
35
|
+
datetime = Kredis.datetime "mydatetime"
|
36
|
+
memoized_midnight = Time.zone.now.midnight
|
37
|
+
datetime.value = memoized_midnight # SET mydatetime "2021-07-27T00:00:00.000000000Z"
|
38
|
+
memoized_midnight == datetime.value # => GET mydatetime
|
39
|
+
|
23
40
|
json = Kredis.json "myjson"
|
24
41
|
json.value = { "one" => 1, "two" => "2" } # => SET myjson "{\"one\":1,\"two\":\"2\"}"
|
25
42
|
{ "one" => 1, "two" => "2" } == json.value # => GET myjson
|
@@ -29,78 +46,110 @@ There are data structures for counters, enums, flags, lists, unique lists, sets,
|
|
29
46
|
|
30
47
|
```ruby
|
31
48
|
list = Kredis.list "mylist"
|
32
|
-
list << "hello world!"
|
33
|
-
[ "hello world!" ] == list.elements
|
49
|
+
list << "hello world!" # => RPUSH mylist "hello world!"
|
50
|
+
[ "hello world!" ] == list.elements # => LRANGE mylist 0, -1
|
34
51
|
|
35
52
|
integer_list = Kredis.list "myintegerlist", typed: :integer
|
36
|
-
integer_list.append([ 1, 2, 3 ]) # =>
|
37
|
-
integer_list << 4 # =>
|
38
|
-
[ 1, 2, 3, 4 ] == integer_list.elements # LRANGE 0 -1
|
53
|
+
integer_list.append([ 1, 2, 3 ]) # => RPUSH myintegerlist "1" "2" "3"
|
54
|
+
integer_list << 4 # => RPUSH myintegerlist "4"
|
55
|
+
[ 1, 2, 3, 4 ] == integer_list.elements # => LRANGE myintegerlist 0 -1
|
39
56
|
|
40
57
|
unique_list = Kredis.unique_list "myuniquelist"
|
41
|
-
unique_list.append(%w[ 2 3 4 ])
|
42
|
-
unique_list.prepend(%w[ 1 2 3 4 ])
|
58
|
+
unique_list.append(%w[ 2 3 4 ]) # => LREM myuniquelist 0, "2" + LREM myuniquelist 0, "3" + LREM myuniquelist 0, "4" + RPUSH myuniquelist "2", "3", "4"
|
59
|
+
unique_list.prepend(%w[ 1 2 3 4 ]) # => LREM myuniquelist 0, "1" + LREM myuniquelist 0, "2" + LREM myuniquelist 0, "3" + LREM myuniquelist 0, "4" + LPUSH myuniquelist "1", "2", "3", "4"
|
43
60
|
unique_list.append([])
|
44
|
-
unique_list << "5"
|
45
|
-
unique_list.remove(3)
|
46
|
-
[ "
|
61
|
+
unique_list << "5" # => LREM myuniquelist 0, "5" + RPUSH myuniquelist "5"
|
62
|
+
unique_list.remove(3) # => LREM myuniquelist 0, "3"
|
63
|
+
[ "4", "2", "1", "5" ] == unique_list.elements # => LRANGE myuniquelist 0, -1
|
47
64
|
|
48
65
|
set = Kredis.set "myset", typed: :datetime
|
49
|
-
set.add(DateTime.tomorrow, DateTime.yesterday)
|
50
|
-
set << DateTime.tomorrow
|
51
|
-
2 == set.size
|
52
|
-
[ DateTime.tomorrow, DateTime.yesterday ] == set.
|
66
|
+
set.add(DateTime.tomorrow, DateTime.yesterday) # => SADD myset "2021-02-03 00:00:00 +0100" "2021-02-01 00:00:00 +0100"
|
67
|
+
set << DateTime.tomorrow # => SADD myset "2021-02-03 00:00:00 +0100"
|
68
|
+
2 == set.size # => SCARD myset
|
69
|
+
[ DateTime.tomorrow, DateTime.yesterday ] == set.members # => SMEMBERS myset
|
70
|
+
|
71
|
+
hash = Kredis.hash "myhash"
|
72
|
+
hash.update("key" => "value", "key2" => "value2") # => HSET myhash "key", "value", "key2", "value2"
|
73
|
+
{ "key" => "value", "key2" => "value2" } == hash.to_h # => HGETALL myhash
|
74
|
+
"value2" == hash["key2"] # => HMGET myhash "key2"
|
75
|
+
%w[ key key2 ] == hash.keys # => HKEYS myhash
|
76
|
+
%w[ value value2 ] == hash.values # => HVALS myhash
|
77
|
+
hash.remove # => DEL myhash
|
78
|
+
|
79
|
+
high_scores = Kredis.hash "high_scores", typed: :integer
|
80
|
+
high_scores.update(space_invaders: 100, pong: 42) # HSET high_scores "space_invaders", "100", "pong", "42"
|
81
|
+
%w[ space_invaders pong ] == high_scores.keys # HKEYS high_scores
|
82
|
+
[ 100, 42 ] == high_scores.values # HVALS high_scores
|
83
|
+
{ "space_invaders" => 100, "pong" => 42 } == high_scores.to_h # HGETALL high_scores
|
53
84
|
|
54
85
|
head_count = Kredis.counter "headcount"
|
55
86
|
0 == head_count.value # => GET "headcount"
|
56
|
-
head_count.increment
|
57
|
-
head_count.increment
|
58
|
-
head_count.decrement
|
87
|
+
head_count.increment # => SET headcount 0 NX + INCRBY headcount 1
|
88
|
+
head_count.increment # => SET headcount 0 NX + INCRBY headcount 1
|
89
|
+
head_count.decrement # => SET headcount 0 NX + DECRBY headcount 1
|
59
90
|
1 == head_count.value # => GET "headcount"
|
60
91
|
|
61
92
|
counter = Kredis.counter "mycounter", expires_in: 5.seconds
|
62
|
-
counter.increment by: 2 # =>
|
93
|
+
counter.increment by: 2 # => SET mycounter 0 EX 5 NX + INCRBY "mycounter" 2
|
63
94
|
2 == counter.value # => GET "mycounter"
|
64
95
|
sleep 6.seconds
|
65
96
|
0 == counter.value # => GET "mycounter"
|
66
97
|
|
98
|
+
cycle = Kredis.cycle "mycycle", values: %i[ one two three ]
|
99
|
+
:one == cycle.value # => GET mycycle
|
100
|
+
cycle.next # => GET mycycle + SET mycycle 1
|
101
|
+
:two == cycle.value # => GET mycycle
|
102
|
+
cycle.next # => GET mycycle + SET mycycle 2
|
103
|
+
:three == cycle.value # => GET mycycle
|
104
|
+
cycle.next # => GET mycycle + SET mycycle 0
|
105
|
+
:one == cycle.value # => GET mycycle
|
106
|
+
|
67
107
|
enum = Kredis.enum "myenum", values: %w[ one two three ], default: "one"
|
68
|
-
"one" == enum.value
|
69
|
-
true == enum.one?
|
70
|
-
enum.value = "two"
|
71
|
-
"two" == enum.value
|
108
|
+
"one" == enum.value # => GET myenum
|
109
|
+
true == enum.one? # => GET myenum
|
110
|
+
enum.value = "two" # => SET myenum "two"
|
111
|
+
"two" == enum.value # => GET myenum
|
72
112
|
enum.value = "four"
|
73
|
-
"two" == enum.value
|
74
|
-
enum.reset
|
75
|
-
"one" == enum.value
|
113
|
+
"two" == enum.value # => GET myenum
|
114
|
+
enum.reset # => DEL myenum
|
115
|
+
"one" == enum.value # => GET myenum
|
76
116
|
|
77
117
|
slots = Kredis.slots "myslots", available: 3
|
78
|
-
true == slots.available?
|
79
|
-
slots.reserve
|
80
|
-
true == slots.available?
|
81
|
-
slots.reserve
|
82
|
-
true == slots.available?
|
83
|
-
slots.reserve
|
84
|
-
|
85
|
-
slots.reserve
|
86
|
-
false == slots.available?
|
87
|
-
slots.release
|
88
|
-
true == slots.available?
|
89
|
-
slots.reset
|
118
|
+
true == slots.available? # => GET myslots
|
119
|
+
slots.reserve # => INCR myslots
|
120
|
+
true == slots.available? # => GET myslots
|
121
|
+
slots.reserve # => INCR myslots
|
122
|
+
true == slots.available? # => GET myslots
|
123
|
+
slots.reserve # => INCR myslots
|
124
|
+
false == slots.available? # => GET myslots
|
125
|
+
slots.reserve # => INCR myslots + DECR myslots
|
126
|
+
false == slots.available? # => GET myslots
|
127
|
+
slots.release # => DECR myslots
|
128
|
+
true == slots.available? # => GET myslots
|
129
|
+
slots.reset # => DEL myslots
|
130
|
+
|
131
|
+
|
132
|
+
slot = Kredis.slot "myslot"
|
133
|
+
true == slot.available? # => GET myslot
|
134
|
+
slot.reserve # => INCR myslot
|
135
|
+
false == slot.available? # => GET myslot
|
136
|
+
slot.release # => DECR myslot
|
137
|
+
true == slot.available? # => GET myslot
|
138
|
+
slot.reset # => DEL myslot
|
90
139
|
|
91
140
|
flag = Kredis.flag "myflag"
|
92
|
-
false == flag.marked?
|
93
|
-
flag.mark
|
94
|
-
true == flag.marked?
|
95
|
-
flag.remove
|
96
|
-
false == flag.marked?
|
97
|
-
|
98
|
-
flag.mark(expires_in: 1.second)
|
99
|
-
true == flag.marked?
|
141
|
+
false == flag.marked? # => EXISTS myflag
|
142
|
+
flag.mark # => SET myflag 1
|
143
|
+
true == flag.marked? # => EXISTS myflag
|
144
|
+
flag.remove # => DEL myflag
|
145
|
+
false == flag.marked? # => EXISTS myflag
|
146
|
+
|
147
|
+
flag.mark(expires_in: 1.second) #=> SET myflag 1 EX 1
|
148
|
+
true == flag.marked? #=> EXISTS myflag
|
100
149
|
sleep 0.5.seconds
|
101
|
-
true == flag.marked?
|
150
|
+
true == flag.marked? #=> EXISTS myflag
|
102
151
|
sleep 0.6.seconds
|
103
|
-
false == flag.marked?
|
152
|
+
false == flag.marked? #=> EXISTS myflag
|
104
153
|
```
|
105
154
|
|
106
155
|
And using structures on a different than the default `shared` redis instance, relying on `config/redis/secondary.yml`:
|
@@ -124,12 +173,23 @@ class Person < ApplicationRecord
|
|
124
173
|
end
|
125
174
|
|
126
175
|
person = Person.find(5)
|
127
|
-
person.names.append "David", "Heinemeier", "Hansson" # =>
|
128
|
-
true == person.morning.bright?
|
129
|
-
person.morning.value = "blue"
|
130
|
-
true == person.morning.blue?
|
176
|
+
person.names.append "David", "Heinemeier", "Hansson" # => RPUSH people:5:names "David" "Heinemeier" "Hansson"
|
177
|
+
true == person.morning.bright? # => GET people:1:morning
|
178
|
+
person.morning.value = "blue" # => SET people:1:morning
|
179
|
+
true == person.morning.blue? # => GET people:1:morning
|
131
180
|
```
|
132
181
|
|
182
|
+
You can also define `after_change` callbacks that trigger on mutations:
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
class Person < ApplicationRecord
|
186
|
+
kredis_list :names, after_change: ->(p) { }
|
187
|
+
kredis_unique_list :skills, limit: 2, after_change: :skillset_changed
|
188
|
+
|
189
|
+
def skillset_changed
|
190
|
+
end
|
191
|
+
end
|
192
|
+
```
|
133
193
|
|
134
194
|
## Installation
|
135
195
|
|
@@ -156,6 +216,32 @@ test:
|
|
156
216
|
|
157
217
|
Additional configurations can be added under `config/redis/*.yml` and referenced when a type is created, e.g. `Kredis.string("mystring", config: :strings)` would lookup `config/redis/strings.yml`. Under the hood `Kredis.configured_for` is called which'll pass the configuration on to `Redis.new`.
|
158
218
|
|
219
|
+
### Setting SSL options on Redis Connections
|
220
|
+
|
221
|
+
If you need to connect to Redis with SSL, the recommended approach is to set your Redis instance manually by adding an entry to the `Kredis::Connections.connections` hash. Below an example showing how to connect to Redis using Client Authentication:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
Kredis::Connections.connections[:shared] = Redis.new(
|
225
|
+
url: ENV['REDIS_URL'],
|
226
|
+
ssl_params: {
|
227
|
+
cert_store: OpenSSL::X509::Store.new.tap { |store|
|
228
|
+
store.add_file(Rails.root.join('config', 'ca_cert.pem').to_s)
|
229
|
+
},
|
230
|
+
|
231
|
+
cert: OpenSSL::X509::Certificate.new(File.read(
|
232
|
+
Rails.root.join('config', 'client.crt')
|
233
|
+
)),
|
234
|
+
|
235
|
+
key: OpenSSL::PKey::RSA.new(
|
236
|
+
Rails.application.credentials.redis[:client_key]
|
237
|
+
),
|
238
|
+
|
239
|
+
verify_mode: OpenSSL::SSL::VERIFY_PEER
|
240
|
+
}
|
241
|
+
)
|
242
|
+
```
|
243
|
+
|
244
|
+
The above code could be added to either `config/environments/production.rb` or an initializer. Please ensure that your client private key, if used, is stored your credentials file or another secure location.
|
159
245
|
|
160
246
|
## License
|
161
247
|
|
data/lib/kredis/attributes.rb
CHANGED
@@ -2,68 +2,87 @@ module Kredis::Attributes
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
class_methods do
|
5
|
-
def kredis_proxy(name, key: nil, config: :shared)
|
6
|
-
kredis_connection_with __method__, name, key, config: config
|
5
|
+
def kredis_proxy(name, key: nil, config: :shared, after_change: nil)
|
6
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change
|
7
7
|
end
|
8
8
|
|
9
|
-
def kredis_string(name, key: nil, config: :shared)
|
10
|
-
kredis_connection_with __method__, name, key, config: config
|
9
|
+
def kredis_string(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
10
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
11
11
|
end
|
12
12
|
|
13
|
-
def kredis_integer(name, key: nil, config: :shared)
|
14
|
-
kredis_connection_with __method__, name, key, config: config
|
13
|
+
def kredis_integer(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
14
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
kredis_connection_with __method__, name, key, config: config
|
17
|
+
def kredis_decimal(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
18
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
kredis_connection_with __method__, name, key, config: config
|
21
|
+
def kredis_datetime(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
22
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
23
|
+
end
|
24
|
+
|
25
|
+
def kredis_flag(name, key: nil, config: :shared, after_change: nil)
|
26
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change
|
23
27
|
|
24
28
|
define_method("#{name}?") do
|
25
29
|
send(name).marked?
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
29
|
-
def
|
30
|
-
kredis_connection_with __method__, name, key,
|
33
|
+
def kredis_float(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
34
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
35
|
+
end
|
36
|
+
|
37
|
+
def kredis_enum(name, key: nil, values:, default:, config: :shared, after_change: nil)
|
38
|
+
kredis_connection_with __method__, name, key, values: values, default: default, config: config, after_change: after_change
|
39
|
+
end
|
40
|
+
|
41
|
+
def kredis_json(name, key: nil, config: :shared, after_change: nil, expires_in: nil)
|
42
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change, expires_in: expires_in
|
31
43
|
end
|
32
44
|
|
33
|
-
def
|
34
|
-
kredis_connection_with __method__, name, key, config: config
|
45
|
+
def kredis_list(name, key: nil, typed: :string, config: :shared, after_change: nil)
|
46
|
+
kredis_connection_with __method__, name, key, typed: typed, config: config, after_change: after_change
|
35
47
|
end
|
36
48
|
|
37
|
-
def
|
38
|
-
kredis_connection_with __method__, name, key, typed: typed, config: config
|
49
|
+
def kredis_unique_list(name, limit: nil, key: nil, typed: :string, config: :shared, after_change: nil)
|
50
|
+
kredis_connection_with __method__, name, key, limit: limit, typed: typed, config: config, after_change: after_change
|
39
51
|
end
|
40
52
|
|
41
|
-
def
|
42
|
-
kredis_connection_with __method__, name, key,
|
53
|
+
def kredis_set(name, key: nil, typed: :string, config: :shared, after_change: nil)
|
54
|
+
kredis_connection_with __method__, name, key, typed: typed, config: config, after_change: after_change
|
43
55
|
end
|
44
56
|
|
45
|
-
def
|
46
|
-
kredis_connection_with __method__, name, key,
|
57
|
+
def kredis_slot(name, key: nil, config: :shared, after_change: nil)
|
58
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change
|
47
59
|
end
|
48
60
|
|
49
|
-
def
|
50
|
-
kredis_connection_with __method__, name, key, config: config
|
61
|
+
def kredis_slots(name, available:, key: nil, config: :shared, after_change: nil)
|
62
|
+
kredis_connection_with __method__, name, key, available: available, config: config, after_change: after_change
|
51
63
|
end
|
52
64
|
|
53
|
-
def
|
54
|
-
kredis_connection_with __method__, name, key,
|
65
|
+
def kredis_counter(name, key: nil, config: :shared, after_change: nil)
|
66
|
+
kredis_connection_with __method__, name, key, config: config, after_change: after_change
|
67
|
+
end
|
68
|
+
|
69
|
+
def kredis_hash(name, key: nil, typed: :string, config: :shared, after_change: nil)
|
70
|
+
kredis_connection_with __method__, name, key, typed: typed, config: config, after_change: after_change
|
55
71
|
end
|
56
72
|
|
57
73
|
private
|
58
74
|
def kredis_connection_with(method, name, key, **options)
|
59
75
|
ivar_symbol = :"@#{name}_#{method}"
|
60
76
|
type = method.to_s.sub("kredis_", "")
|
77
|
+
after_change = options.delete(:after_change)
|
61
78
|
|
62
79
|
define_method(name) do
|
63
80
|
if instance_variable_defined?(ivar_symbol)
|
64
81
|
instance_variable_get(ivar_symbol)
|
65
82
|
else
|
66
|
-
|
83
|
+
new_type = Kredis.send(type, kredis_key_evaluated(key) || kredis_key_for_attribute(name), **options)
|
84
|
+
instance_variable_set ivar_symbol,
|
85
|
+
after_change ? enrich_after_change_with_record_access(new_type, after_change) : new_type
|
67
86
|
end
|
68
87
|
end
|
69
88
|
end
|
@@ -84,4 +103,11 @@ module Kredis::Attributes
|
|
84
103
|
def extract_kredis_id
|
85
104
|
try(:id) or raise NotImplementedError, "kredis needs a unique id, either implement an id method or pass a custom key."
|
86
105
|
end
|
106
|
+
|
107
|
+
def enrich_after_change_with_record_access(type, original_after_change)
|
108
|
+
case original_after_change
|
109
|
+
when Proc then Kredis::Types::CallbacksProxy.new(type, ->(_) { original_after_change.call(self) })
|
110
|
+
when Symbol then Kredis::Types::CallbacksProxy.new(type, ->(_) { send(original_after_change) })
|
111
|
+
end
|
112
|
+
end
|
87
113
|
end
|
data/lib/kredis/connections.rb
CHANGED
@@ -6,13 +6,22 @@ module Kredis::Connections
|
|
6
6
|
|
7
7
|
def configured_for(name)
|
8
8
|
connections[name] ||= begin
|
9
|
-
|
10
|
-
|
9
|
+
Kredis.instrument :meta, message: "Connected to #{name}" do
|
10
|
+
Redis.new configurator.config_for("redis/#{name}")
|
11
|
+
end
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
15
|
def clear_all
|
15
|
-
|
16
|
-
|
16
|
+
Kredis.instrument :meta, message: "Connections all cleared" do
|
17
|
+
connections.each_value do |connection|
|
18
|
+
if Kredis.namespace
|
19
|
+
keys = connection.keys("#{Kredis.namespace}:*")
|
20
|
+
connection.del keys if keys.any?
|
21
|
+
else
|
22
|
+
connection.flushdb
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "active_support/log_subscriber"
|
2
|
+
|
3
|
+
class Kredis::LogSubscriber < ActiveSupport::LogSubscriber
|
4
|
+
def proxy(event)
|
5
|
+
debug formatted_in(YELLOW, event, type: "Proxy")
|
6
|
+
end
|
7
|
+
|
8
|
+
def migration(event)
|
9
|
+
debug formatted_in(YELLOW, event, type: "Migration")
|
10
|
+
end
|
11
|
+
|
12
|
+
def meta(event)
|
13
|
+
info formatted_in(MAGENTA, event)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def formatted_in(color, event, type: nil)
|
18
|
+
color " Kredis #{type} (#{event.duration.round(1)}ms) #{event.payload[:message]}", color, true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Kredis::LogSubscriber.attach_to :kredis
|
data/lib/kredis/migration.rb
CHANGED
@@ -5,6 +5,7 @@ class Kredis::Migration
|
|
5
5
|
|
6
6
|
def initialize(config = :shared)
|
7
7
|
@redis = Kredis.configured_for config
|
8
|
+
# TODO: Replace script loading with `copy` command once Redis 6.2+ is the minimum supported version.
|
8
9
|
@copy_sha = @redis.script "load", "redis.call('SETNX', KEYS[2], redis.call('GET', KEYS[1])); return 1;"
|
9
10
|
end
|
10
11
|
|
@@ -21,8 +22,9 @@ class Kredis::Migration
|
|
21
22
|
namespaced_to = Kredis.namespaced_key(to)
|
22
23
|
|
23
24
|
if to.present? && from != namespaced_to
|
24
|
-
log_migration "Migrating key #{from} to #{namespaced_to}"
|
25
|
-
|
25
|
+
log_migration "Migrating key #{from} to #{namespaced_to}" do
|
26
|
+
@redis.evalsha @copy_sha, keys: [ from, namespaced_to ]
|
27
|
+
end
|
26
28
|
else
|
27
29
|
log_migration "Skipping blank/unaltered migration key #{from} → #{to}"
|
28
30
|
end
|
@@ -45,7 +47,7 @@ class Kredis::Migration
|
|
45
47
|
end until cursor == "0"
|
46
48
|
end
|
47
49
|
|
48
|
-
def log_migration(message)
|
49
|
-
Kredis.
|
50
|
+
def log_migration(message, &block)
|
51
|
+
Kredis.instrument :migration, message: message, &block
|
50
52
|
end
|
51
53
|
end
|
data/lib/kredis/railtie.rb
CHANGED
@@ -1,33 +1,29 @@
|
|
1
|
-
|
1
|
+
class Kredis::Railtie < ::Rails::Railtie
|
2
|
+
config.kredis = ActiveSupport::OrderedOptions.new
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
initializer "kredis.testing" do
|
8
|
-
ActiveSupport.on_load(:active_support_test_case) do
|
9
|
-
parallelize_setup { |worker| Kredis.namespace = "test-#{worker}" }
|
10
|
-
teardown { Kredis.clear_all }
|
11
|
-
end
|
4
|
+
initializer "kredis.testing" do
|
5
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
6
|
+
parallelize_setup { |worker| Kredis.namespace = "test-#{worker}" }
|
7
|
+
teardown { Kredis.clear_all }
|
12
8
|
end
|
9
|
+
end
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
initializer "kredis.logger" do
|
12
|
+
Kredis::LogSubscriber.logger = config.kredis.logger || Rails.logger
|
13
|
+
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
initializer "kredis.configurator" do
|
16
|
+
Kredis.configurator = Rails.application
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
initializer "kredis.attributes" do
|
20
|
+
# No load hook for Active Model, just defer until after initialization.
|
21
|
+
config.after_initialize do
|
22
|
+
ActiveModel::Model.include Kredis::Attributes if defined?(ActiveModel::Model)
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
25
|
+
ActiveSupport.on_load(:active_record) do
|
26
|
+
include Kredis::Attributes
|
31
27
|
end
|
32
28
|
end
|
33
29
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kredis
|
4
|
+
module Type
|
5
|
+
class Json < ActiveModel::Type::Value
|
6
|
+
def type
|
7
|
+
:json
|
8
|
+
end
|
9
|
+
|
10
|
+
def cast_value(value)
|
11
|
+
JSON.load(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(value)
|
15
|
+
JSON.dump(value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/kredis/type_casting.rb
CHANGED
@@ -1,45 +1,35 @@
|
|
1
|
+
require "json"
|
2
|
+
require "active_model/type"
|
3
|
+
require "kredis/type/json"
|
4
|
+
require "kredis/type/datetime"
|
5
|
+
|
1
6
|
module Kredis::TypeCasting
|
2
7
|
class InvalidType < StandardError; end
|
3
8
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
when Time, DateTime, ActiveSupport::TimeWithZone
|
19
|
-
value.iso8601(9)
|
20
|
-
when Hash
|
21
|
-
JSON.dump(value)
|
22
|
-
else
|
23
|
-
value
|
24
|
-
end
|
9
|
+
TYPES = {
|
10
|
+
string: ActiveModel::Type::String.new,
|
11
|
+
integer: ActiveModel::Type::Integer.new,
|
12
|
+
decimal: ActiveModel::Type::Decimal.new,
|
13
|
+
float: ActiveModel::Type::Float.new,
|
14
|
+
boolean: ActiveModel::Type::Boolean.new,
|
15
|
+
datetime: Kredis::Type::DateTime.new,
|
16
|
+
json: Kredis::Type::Json.new
|
17
|
+
}
|
18
|
+
|
19
|
+
def type_to_string(value, type)
|
20
|
+
raise InvalidType if type && !TYPES.key?(type)
|
21
|
+
|
22
|
+
TYPES[type || :string].serialize(value)
|
25
23
|
end
|
26
24
|
|
27
25
|
def string_to_type(value, type)
|
28
|
-
raise InvalidType if type && !
|
29
|
-
|
30
|
-
|
31
|
-
when nil, :string then value
|
32
|
-
when :integer then value.to_i
|
33
|
-
when :decimal then value.to_d
|
34
|
-
when :float then value.to_f
|
35
|
-
when :boolean then value == "t" ? true : false
|
36
|
-
when :datetime then Time.iso8601(value)
|
37
|
-
when :json then JSON.load(value)
|
38
|
-
end if value.present?
|
26
|
+
raise InvalidType if type && !TYPES.key?(type)
|
27
|
+
|
28
|
+
TYPES[type || :string].cast(value)
|
39
29
|
end
|
40
30
|
|
41
|
-
def types_to_strings(values)
|
42
|
-
Array(values).flatten.map { |value| type_to_string(value) }
|
31
|
+
def types_to_strings(values, type)
|
32
|
+
Array(values).flatten.map { |value| type_to_string(value, type) }
|
43
33
|
end
|
44
34
|
|
45
35
|
def strings_to_types(values, type)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Kredis::Types::CallbacksProxy
|
2
|
+
attr_reader :type
|
3
|
+
delegate :to_s, to: :type
|
4
|
+
|
5
|
+
AFTER_CHANGE_OPERATIONS = {
|
6
|
+
Kredis::Types::Counter => %i[ increment decrement reset ],
|
7
|
+
Kredis::Types::Cycle => %i[ next ],
|
8
|
+
Kredis::Types::Enum => %i[ value= reset ],
|
9
|
+
Kredis::Types::Flag => %i[ mark remove ],
|
10
|
+
Kredis::Types::Hash => %i[ update delete ],
|
11
|
+
Kredis::Types::List => %i[ remove prepend append << ],
|
12
|
+
Kredis::Types::Scalar => %i[ value= clear ],
|
13
|
+
Kredis::Types::Set => %i[ add << remove replace take clear ],
|
14
|
+
Kredis::Types::Slots => %i[ reserve release reset ]
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(type, callback)
|
18
|
+
@type, @callback = type, callback
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(method, *args, **kwargs, &block)
|
22
|
+
result = type.send(method, *args, **kwargs, &block)
|
23
|
+
invoke_suitable_after_change_callback_for method
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def invoke_suitable_after_change_callback_for(method)
|
29
|
+
@callback.call(type) if AFTER_CHANGE_OPERATIONS[type.class]&.include? method
|
30
|
+
end
|
31
|
+
end
|
data/lib/kredis/types/counter.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Kredis::Types::Counter < Kredis::Types::Proxying
|
2
|
-
proxying :multi, :set, :incrby, :decrby, :get
|
2
|
+
proxying :multi, :set, :incrby, :decrby, :get, :del
|
3
3
|
|
4
4
|
attr_accessor :expires_in
|
5
5
|
|
@@ -20,4 +20,8 @@ class Kredis::Types::Counter < Kredis::Types::Proxying
|
|
20
20
|
def value
|
21
21
|
get.to_i
|
22
22
|
end
|
23
|
+
|
24
|
+
def reset
|
25
|
+
del
|
26
|
+
end
|
23
27
|
end
|
data/lib/kredis/types/enum.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "active_support/core_ext/hash"
|
2
|
+
|
3
|
+
class Kredis::Types::Hash < Kredis::Types::Proxying
|
4
|
+
proxying :hget, :hset, :hmget, :hdel, :hgetall, :hkeys, :hvals, :del
|
5
|
+
|
6
|
+
attr_accessor :typed
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
string_to_type(hget(key), typed)
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
update key => value
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(**entries)
|
17
|
+
hset entries.transform_values{ |val| type_to_string(val, typed) } if entries.flatten.any?
|
18
|
+
end
|
19
|
+
|
20
|
+
def values_at(*keys)
|
21
|
+
strings_to_types(hmget(keys) || [], typed)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(*keys)
|
25
|
+
hdel keys if keys.flatten.any?
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove
|
29
|
+
del
|
30
|
+
end
|
31
|
+
|
32
|
+
def entries
|
33
|
+
(hgetall || {}).transform_values { |val| string_to_type(val, typed) }.with_indifferent_access
|
34
|
+
end
|
35
|
+
alias to_h entries
|
36
|
+
|
37
|
+
def keys
|
38
|
+
hkeys || []
|
39
|
+
end
|
40
|
+
|
41
|
+
def values
|
42
|
+
strings_to_types(hvals || [], typed)
|
43
|
+
end
|
44
|
+
end
|
data/lib/kredis/types/list.rb
CHANGED
@@ -9,15 +9,15 @@ class Kredis::Types::List < Kredis::Types::Proxying
|
|
9
9
|
alias to_a elements
|
10
10
|
|
11
11
|
def remove(*elements)
|
12
|
-
types_to_strings(elements).each { |element| lrem 0, element }
|
12
|
+
types_to_strings(elements, typed).each { |element| lrem 0, element }
|
13
13
|
end
|
14
14
|
|
15
15
|
def prepend(*elements)
|
16
|
-
lpush types_to_strings(elements) if elements.flatten.any?
|
16
|
+
lpush types_to_strings(elements, typed) if elements.flatten.any?
|
17
17
|
end
|
18
18
|
|
19
19
|
def append(*elements)
|
20
|
-
rpush types_to_strings(elements) if elements.flatten.any?
|
20
|
+
rpush types_to_strings(elements, typed) if elements.flatten.any?
|
21
21
|
end
|
22
22
|
alias << append
|
23
23
|
end
|
data/lib/kredis/types/proxy.rb
CHANGED
@@ -14,9 +14,10 @@ class Kredis::Types::Proxy
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def method_missing(method, *args, **kwargs)
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
Kredis.instrument :proxy, **log_message(method, *args, **kwargs) do
|
18
|
+
failsafe do
|
19
|
+
redis.public_send method, key, *args, **kwargs
|
20
|
+
end
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
@@ -24,8 +25,7 @@ class Kredis::Types::Proxy
|
|
24
25
|
def log_message(method, *args, **kwargs)
|
25
26
|
args = args.flatten.reject(&:blank?).presence
|
26
27
|
kwargs = kwargs.reject { |_k, v| v.blank? }.presence
|
27
|
-
type_name = self.class.name.split("::").last
|
28
28
|
|
29
|
-
|
29
|
+
{ message: "#{method.upcase} #{key} #{args&.inspect} #{kwargs&.inspect}".chomp }
|
30
30
|
end
|
31
31
|
end
|
data/lib/kredis/types/scalar.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
class Kredis::Types::Scalar < Kredis::Types::Proxying
|
2
|
-
proxying :set, :get, :exists?, :del
|
2
|
+
proxying :set, :get, :exists?, :del, :expire, :expireat
|
3
3
|
|
4
|
-
attr_accessor :typed, :default
|
4
|
+
attr_accessor :typed, :default, :expires_in
|
5
5
|
|
6
6
|
def value=(value)
|
7
|
-
set type_to_string(value)
|
7
|
+
set type_to_string(value, typed), ex: expires_in
|
8
8
|
end
|
9
9
|
|
10
10
|
def value
|
11
|
-
string_to_type(get, typed)
|
11
|
+
value_after_casting = string_to_type(get, typed)
|
12
|
+
|
13
|
+
if value_after_casting.nil?
|
14
|
+
default
|
15
|
+
else
|
16
|
+
value_after_casting
|
17
|
+
end
|
12
18
|
end
|
13
19
|
|
14
20
|
def to_s
|
@@ -22,4 +28,12 @@ class Kredis::Types::Scalar < Kredis::Types::Proxying
|
|
22
28
|
def clear
|
23
29
|
del
|
24
30
|
end
|
31
|
+
|
32
|
+
def expire_in(seconds)
|
33
|
+
expire seconds.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def expire_at(datetime)
|
37
|
+
expireat datetime.to_i
|
38
|
+
end
|
25
39
|
end
|
data/lib/kredis/types/set.rb
CHANGED
@@ -9,12 +9,12 @@ class Kredis::Types::Set < Kredis::Types::Proxying
|
|
9
9
|
alias to_a members
|
10
10
|
|
11
11
|
def add(*members)
|
12
|
-
sadd types_to_strings(members) if members.flatten.any?
|
12
|
+
sadd types_to_strings(members, typed) if members.flatten.any?
|
13
13
|
end
|
14
14
|
alias << add
|
15
15
|
|
16
16
|
def remove(*members)
|
17
|
-
srem types_to_strings(members) if members.flatten.any?
|
17
|
+
srem types_to_strings(members, typed) if members.flatten.any?
|
18
18
|
end
|
19
19
|
|
20
20
|
def replace(*members)
|
@@ -25,7 +25,7 @@ class Kredis::Types::Set < Kredis::Types::Proxying
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def include?(member)
|
28
|
-
sismember type_to_string(member)
|
28
|
+
sismember type_to_string(member, typed)
|
29
29
|
end
|
30
30
|
|
31
31
|
def size
|
data/lib/kredis/types.rb
CHANGED
@@ -1,73 +1,90 @@
|
|
1
1
|
module Kredis::Types
|
2
|
-
|
3
|
-
|
2
|
+
autoload :CallbacksProxy, "kredis/types/callbacks_proxy"
|
3
|
+
|
4
|
+
def proxy(key, config: :shared, after_change: nil)
|
5
|
+
type_from(Proxy, config, key, after_change: after_change)
|
4
6
|
end
|
5
7
|
|
6
8
|
|
7
|
-
def scalar(key, typed: :string, default: nil, config: :shared)
|
8
|
-
Scalar
|
9
|
+
def scalar(key, typed: :string, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
10
|
+
type_from(Scalar, config, key, after_change: after_change, typed: typed, default: default, expires_in: expires_in)
|
11
|
+
end
|
12
|
+
|
13
|
+
def string(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
14
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :string, default: default, expires_in: expires_in)
|
9
15
|
end
|
10
16
|
|
11
|
-
def
|
12
|
-
Scalar
|
17
|
+
def integer(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
18
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :integer, default: default, expires_in: expires_in)
|
13
19
|
end
|
14
20
|
|
15
|
-
def
|
16
|
-
Scalar
|
21
|
+
def decimal(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
22
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :decimal, default: default, expires_in: expires_in)
|
17
23
|
end
|
18
24
|
|
19
|
-
def
|
20
|
-
Scalar
|
25
|
+
def float(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
26
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :float, default: default, expires_in: expires_in)
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
24
|
-
Scalar
|
29
|
+
def boolean(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
30
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :boolean, default: default, expires_in: expires_in)
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
Scalar
|
33
|
+
def datetime(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
34
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :datetime, default: default, expires_in: expires_in)
|
29
35
|
end
|
30
36
|
|
31
|
-
def
|
32
|
-
Scalar
|
37
|
+
def json(key, default: nil, config: :shared, after_change: nil, expires_in: nil)
|
38
|
+
type_from(Scalar, config, key, after_change: after_change, typed: :json, default: default, expires_in: expires_in)
|
33
39
|
end
|
34
40
|
|
35
|
-
|
36
|
-
|
41
|
+
|
42
|
+
def counter(key, expires_in: nil, config: :shared, after_change: nil)
|
43
|
+
type_from(Counter, config, key, after_change: after_change, expires_in: expires_in)
|
37
44
|
end
|
38
45
|
|
46
|
+
def cycle(key, values:, expires_in: nil, config: :shared, after_change: nil)
|
47
|
+
type_from(Cycle, config, key, after_change: after_change, values: values, expires_in: expires_in)
|
48
|
+
end
|
39
49
|
|
40
|
-
def
|
41
|
-
|
50
|
+
def flag(key, config: :shared, after_change: nil)
|
51
|
+
type_from(Flag, config, key, after_change: after_change)
|
42
52
|
end
|
43
53
|
|
44
|
-
def
|
45
|
-
|
54
|
+
def enum(key, values:, default:, config: :shared, after_change: nil)
|
55
|
+
type_from(Enum, config, key, after_change: after_change, values: values, default: default)
|
46
56
|
end
|
47
57
|
|
48
|
-
def
|
49
|
-
|
58
|
+
def hash(key, typed: :string, config: :shared, after_change: nil)
|
59
|
+
type_from(Hash, config, key, after_change: after_change, typed: typed)
|
50
60
|
end
|
51
61
|
|
52
|
-
def list(key, typed: :string, config: :shared)
|
53
|
-
List
|
62
|
+
def list(key, typed: :string, config: :shared, after_change: nil)
|
63
|
+
type_from(List, config, key, after_change: after_change, typed: typed)
|
54
64
|
end
|
55
65
|
|
56
|
-
def unique_list(key, typed: :string, limit: nil, config: :shared)
|
57
|
-
UniqueList
|
66
|
+
def unique_list(key, typed: :string, limit: nil, config: :shared, after_change: nil)
|
67
|
+
type_from(UniqueList, config, key, after_change: after_change, typed: typed, limit: limit)
|
58
68
|
end
|
59
69
|
|
60
|
-
def set(key, typed: :string, config: :shared)
|
61
|
-
Set
|
70
|
+
def set(key, typed: :string, config: :shared, after_change: nil)
|
71
|
+
type_from(Set, config, key, after_change: after_change, typed: typed)
|
62
72
|
end
|
63
73
|
|
64
|
-
def slot(key, config: :shared)
|
65
|
-
Slots
|
74
|
+
def slot(key, config: :shared, after_change: nil)
|
75
|
+
type_from(Slots, config, key, after_change: after_change, available: 1)
|
66
76
|
end
|
67
77
|
|
68
|
-
def slots(key, available:, config: :shared)
|
69
|
-
Slots
|
78
|
+
def slots(key, available:, config: :shared, after_change: nil)
|
79
|
+
type_from(Slots, config, key, after_change: after_change, available: available)
|
70
80
|
end
|
81
|
+
|
82
|
+
private
|
83
|
+
def type_from(type_klass, config, key, after_change: nil, **options)
|
84
|
+
type_klass.new(configured_for(config), namespaced_key(key), **options).then do |type|
|
85
|
+
after_change ? CallbacksProxy.new(type, after_change) : type
|
86
|
+
end
|
87
|
+
end
|
71
88
|
end
|
72
89
|
|
73
90
|
require "kredis/types/proxy"
|
@@ -75,8 +92,10 @@ require "kredis/types/proxying"
|
|
75
92
|
|
76
93
|
require "kredis/types/scalar"
|
77
94
|
require "kredis/types/counter"
|
95
|
+
require "kredis/types/cycle"
|
78
96
|
require "kredis/types/flag"
|
79
97
|
require "kredis/types/enum"
|
98
|
+
require "kredis/types/hash"
|
80
99
|
require "kredis/types/list"
|
81
100
|
require "kredis/types/unique_list"
|
82
101
|
require "kredis/types/set"
|
data/lib/kredis/version.rb
CHANGED
data/lib/kredis.rb
CHANGED
@@ -1,20 +1,30 @@
|
|
1
|
-
require "
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
|
+
|
2
4
|
require "kredis/version"
|
3
5
|
|
4
6
|
require "kredis/connections"
|
7
|
+
require "kredis/log_subscriber"
|
5
8
|
require "kredis/namespace"
|
9
|
+
require "kredis/type_casting"
|
6
10
|
require "kredis/types"
|
7
11
|
require "kredis/attributes"
|
8
|
-
require "kredis/type_casting"
|
9
12
|
|
10
|
-
|
11
|
-
include Connections, Namespace, Types, TypeCasting
|
13
|
+
require "kredis/railtie" if defined?(Rails::Railtie)
|
12
14
|
|
15
|
+
module Kredis
|
16
|
+
include Connections, Namespace, TypeCasting, Types
|
13
17
|
extend self
|
14
18
|
|
19
|
+
autoload :Migration, "kredis/migration"
|
20
|
+
|
15
21
|
mattr_accessor :logger
|
16
22
|
|
17
23
|
def redis(config: :shared)
|
18
24
|
configured_for(config)
|
19
25
|
end
|
26
|
+
|
27
|
+
def instrument(channel, **options, &block)
|
28
|
+
ActiveSupport::Notifications.instrument("#{channel}.kredis", **options, &block)
|
29
|
+
end
|
20
30
|
end
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
8
8
|
- David Heinemeier Hansson
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
@@ -39,7 +39,21 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '4.2'
|
42
|
-
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rails
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 6.0.0
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 6.0.0
|
56
|
+
description:
|
43
57
|
email: david@hey.com
|
44
58
|
executables: []
|
45
59
|
extensions: []
|
@@ -50,14 +64,20 @@ files:
|
|
50
64
|
- lib/kredis.rb
|
51
65
|
- lib/kredis/attributes.rb
|
52
66
|
- lib/kredis/connections.rb
|
67
|
+
- lib/kredis/log_subscriber.rb
|
53
68
|
- lib/kredis/migration.rb
|
54
69
|
- lib/kredis/namespace.rb
|
55
70
|
- lib/kredis/railtie.rb
|
71
|
+
- lib/kredis/type/datetime.rb
|
72
|
+
- lib/kredis/type/json.rb
|
56
73
|
- lib/kredis/type_casting.rb
|
57
74
|
- lib/kredis/types.rb
|
75
|
+
- lib/kredis/types/callbacks_proxy.rb
|
58
76
|
- lib/kredis/types/counter.rb
|
77
|
+
- lib/kredis/types/cycle.rb
|
59
78
|
- lib/kredis/types/enum.rb
|
60
79
|
- lib/kredis/types/flag.rb
|
80
|
+
- lib/kredis/types/hash.rb
|
61
81
|
- lib/kredis/types/list.rb
|
62
82
|
- lib/kredis/types/proxy.rb
|
63
83
|
- lib/kredis/types/proxy/failsafe.rb
|
@@ -71,7 +91,7 @@ homepage: https://github.com/rails/kredis
|
|
71
91
|
licenses:
|
72
92
|
- MIT
|
73
93
|
metadata: {}
|
74
|
-
post_install_message:
|
94
|
+
post_install_message:
|
75
95
|
rdoc_options: []
|
76
96
|
require_paths:
|
77
97
|
- lib
|
@@ -86,8 +106,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
106
|
- !ruby/object:Gem::Version
|
87
107
|
version: '0'
|
88
108
|
requirements: []
|
89
|
-
rubygems_version: 3.1.
|
90
|
-
signing_key:
|
109
|
+
rubygems_version: 3.1.4
|
110
|
+
signing_key:
|
91
111
|
specification_version: 4
|
92
112
|
summary: Higher-level data structures built on Redis.
|
93
113
|
test_files: []
|