redis 5.0.7 → 5.1.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/CHANGELOG.md +11 -0
- data/README.md +26 -6
- data/lib/redis/client.rb +7 -11
- data/lib/redis/commands/bitmaps.rb +10 -3
- data/lib/redis/commands/keys.rb +16 -0
- data/lib/redis/commands/pubsub.rb +21 -0
- data/lib/redis/distributed.rb +14 -4
- data/lib/redis/subscribe.rb +29 -1
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +1 -16
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab20cee7f44b7d5f2736e1fbc7073cb950f52ceefc3dc1ff0edf9b4b778c7d8d
|
4
|
+
data.tar.gz: 76b0b6169311906b2ee634f9314c74052a1612245d7e33220aab5cb2c617af8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 220927cf03b0ad6ab0c7340d9b32ed073e379974d054eba12cf966ad65837eba00f114d1fdeb166780ead645befcc3ee9fb3a83aab8e8cb0b1661370f401f8cb
|
7
|
+
data.tar.gz: 8f9476be4c7d4a3dd8dc1f29265b184932f67b49d524a0c79865dc95eee3ba165e9d24cb3f699ce287b886cc4f38b88574a5b33b1bab48f2fe9971597b7d2c5c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 5.1.0
|
4
|
+
|
5
|
+
- `multi` now accept a `watch` keyword argument like `redis-client`. See #1236.
|
6
|
+
- `bitcount` and `bitpos` now accept a `scale:` argument on Redis 7+. See #1242
|
7
|
+
- Added `expiretime` and `pexpiretime`. See #1248.
|
8
|
+
|
9
|
+
# 5.0.8
|
10
|
+
|
11
|
+
- Fix `Redis#without_reconnect` for sentinel clients. Fix #1212.
|
12
|
+
- Add `sentinel_username`, `sentinel_password` for sentinel clients. Bump `redis-client` to `>=0.17.0`. See #1213
|
13
|
+
|
3
14
|
# 5.0.7
|
4
15
|
|
5
16
|
- Fix compatibility with `redis-client 0.15.0` when using Redis Sentinel. Fix #1209.
|
data/README.md
CHANGED
@@ -120,19 +120,39 @@ but a few so that if one is down the client will try the next one. The client
|
|
120
120
|
is able to remember the last Sentinel that was able to reply correctly and will
|
121
121
|
use it for the next requests.
|
122
122
|
|
123
|
-
|
123
|
+
To [authenticate](https://redis.io/docs/management/sentinel/#configuring-sentinel-instances-with-authentication) Sentinel itself, you can specify the `sentinel_username` and `sentinel_password`. Exclude the `sentinel_username` option if you're using password-only authentication.
|
124
124
|
|
125
125
|
```ruby
|
126
|
-
SENTINELS = [{ host: '127.0.0.1', port: 26380
|
127
|
-
{ host: '127.0.0.1', port: 26381
|
126
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380},
|
127
|
+
{ host: '127.0.0.1', port: 26381}]
|
128
128
|
|
129
|
-
redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, role: :master)
|
129
|
+
redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, sentinel_username: 'appuser', sentinel_password: 'mysecret', role: :master)
|
130
130
|
```
|
131
131
|
|
132
|
-
|
132
|
+
If you specify a username and/or password at the top level for your main Redis instance, Sentinel *will not* using thouse credentials
|
133
133
|
|
134
134
|
```ruby
|
135
|
-
|
135
|
+
# Use 'mysecret' to authenticate against the mymaster instance, but skip authentication for the sentinels:
|
136
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380 },
|
137
|
+
{ host: '127.0.0.1', port: 26381 }]
|
138
|
+
|
139
|
+
redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret')
|
140
|
+
```
|
141
|
+
|
142
|
+
So you have to provide Sentinel credential and Redis explictly even they are the same
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# Use 'mysecret' to authenticate against the mymaster instance and sentinel
|
146
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380 },
|
147
|
+
{ host: '127.0.0.1', port: 26381 }]
|
148
|
+
|
149
|
+
redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret', sentinel_password: 'mysecret')
|
150
|
+
```
|
151
|
+
|
152
|
+
Also the `name`, `password`, `username` and `db` for Redis instance can be passed as an url:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
redis = Redis.new(url: "redis://appuser:mysecret@mymaster/10", sentinels: SENTINELS, role: :master)
|
136
156
|
```
|
137
157
|
|
138
158
|
## Cluster support
|
data/lib/redis/client.rb
CHANGED
@@ -27,18 +27,18 @@ class Redis
|
|
27
27
|
super(protocol: 2, **kwargs, client_implementation: ::RedisClient)
|
28
28
|
end
|
29
29
|
|
30
|
-
def translate_error!(error)
|
31
|
-
redis_error = translate_error_class(error.class)
|
30
|
+
def translate_error!(error, mapping: ERROR_MAPPING)
|
31
|
+
redis_error = translate_error_class(error.class, mapping: mapping)
|
32
32
|
raise redis_error, error.message, error.backtrace
|
33
33
|
end
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
def translate_error_class(error_class)
|
38
|
-
|
37
|
+
def translate_error_class(error_class, mapping: ERROR_MAPPING)
|
38
|
+
mapping.fetch(error_class)
|
39
39
|
rescue IndexError
|
40
|
-
if (client_error = error_class.ancestors.find { |a|
|
41
|
-
|
40
|
+
if (client_error = error_class.ancestors.find { |a| mapping[a] })
|
41
|
+
mapping[error_class] = mapping[client_error]
|
42
42
|
else
|
43
43
|
raise
|
44
44
|
end
|
@@ -111,16 +111,12 @@ class Redis
|
|
111
111
|
Client.translate_error!(error)
|
112
112
|
end
|
113
113
|
|
114
|
-
def multi
|
114
|
+
def multi(watch: nil)
|
115
115
|
super
|
116
116
|
rescue ::RedisClient::Error => error
|
117
117
|
Client.translate_error!(error)
|
118
118
|
end
|
119
119
|
|
120
|
-
def disable_reconnection(&block)
|
121
|
-
ensure_connected(retryable: false, &block)
|
122
|
-
end
|
123
|
-
|
124
120
|
def inherit_socket!
|
125
121
|
@inherit_socket = true
|
126
122
|
end
|
@@ -27,9 +27,13 @@ class Redis
|
|
27
27
|
# @param [String] key
|
28
28
|
# @param [Integer] start start index
|
29
29
|
# @param [Integer] stop stop index
|
30
|
+
# @param [String, Symbol] scale the scale of the offset range
|
31
|
+
# e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bits
|
30
32
|
# @return [Integer] the number of bits set to 1
|
31
|
-
def bitcount(key, start = 0, stop = -1)
|
32
|
-
|
33
|
+
def bitcount(key, start = 0, stop = -1, scale: nil)
|
34
|
+
command = [:bitcount, key, start, stop]
|
35
|
+
command << scale if scale
|
36
|
+
send_command(command)
|
33
37
|
end
|
34
38
|
|
35
39
|
# Perform a bitwise operation between strings and store the resulting string in a key.
|
@@ -51,14 +55,17 @@ class Redis
|
|
51
55
|
# @param [Integer] bit whether to look for the first 1 or 0 bit
|
52
56
|
# @param [Integer] start start index
|
53
57
|
# @param [Integer] stop stop index
|
58
|
+
# @param [String, Symbol] scale the scale of the offset range
|
59
|
+
# e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bits
|
54
60
|
# @return [Integer] the position of the first 1/0 bit.
|
55
61
|
# -1 if looking for 1 and it is not found or start and stop are given.
|
56
|
-
def bitpos(key, bit, start = nil, stop = nil)
|
62
|
+
def bitpos(key, bit, start = nil, stop = nil, scale: nil)
|
57
63
|
raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
|
58
64
|
|
59
65
|
command = [:bitpos, key, bit]
|
60
66
|
command << start if start
|
61
67
|
command << stop if stop
|
68
|
+
command << scale if scale
|
62
69
|
send_command(command)
|
63
70
|
end
|
64
71
|
end
|
data/lib/redis/commands/keys.rb
CHANGED
@@ -105,6 +105,14 @@ class Redis
|
|
105
105
|
send_command(args, &Boolify)
|
106
106
|
end
|
107
107
|
|
108
|
+
# Get a key's expiry time specified as number of seconds from UNIX Epoch
|
109
|
+
#
|
110
|
+
# @param [String] key
|
111
|
+
# @return [Integer] expiry time specified as number of seconds from UNIX Epoch
|
112
|
+
def expiretime(key)
|
113
|
+
send_command([:expiretime, key])
|
114
|
+
end
|
115
|
+
|
108
116
|
# Get the time to live (in seconds) for a key.
|
109
117
|
#
|
110
118
|
# @param [String] key
|
@@ -161,6 +169,14 @@ class Redis
|
|
161
169
|
send_command(args, &Boolify)
|
162
170
|
end
|
163
171
|
|
172
|
+
# Get a key's expiry time specified as number of milliseconds from UNIX Epoch
|
173
|
+
#
|
174
|
+
# @param [String] key
|
175
|
+
# @return [Integer] expiry time specified as number of milliseconds from UNIX Epoch
|
176
|
+
def pexpiretime(key)
|
177
|
+
send_command([:pexpiretime, key])
|
178
|
+
end
|
179
|
+
|
164
180
|
# Get the time to live (in milliseconds) for a key.
|
165
181
|
#
|
166
182
|
# @param [String] key
|
@@ -49,6 +49,27 @@ class Redis
|
|
49
49
|
def pubsub(subcommand, *args)
|
50
50
|
send_command([:pubsub, subcommand] + args)
|
51
51
|
end
|
52
|
+
|
53
|
+
# Post a message to a channel in a shard.
|
54
|
+
def spublish(channel, message)
|
55
|
+
send_command([:spublish, channel, message])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Listen for messages published to the given channels in a shard.
|
59
|
+
def ssubscribe(*channels, &block)
|
60
|
+
_subscription(:ssubscribe, 0, channels, block)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Listen for messages published to the given channels in a shard.
|
64
|
+
# Throw a timeout error if there is no messages for a timeout period.
|
65
|
+
def ssubscribe_with_timeout(timeout, *channels, &block)
|
66
|
+
_subscription(:ssubscribe_with_timeout, timeout, channels, block)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Stop listening for messages posted to the given channels in a shard.
|
70
|
+
def sunsubscribe(*channels)
|
71
|
+
_subscription(:sunsubscribe, 0, channels, nil)
|
72
|
+
end
|
52
73
|
end
|
53
74
|
end
|
54
75
|
end
|
data/lib/redis/distributed.rb
CHANGED
@@ -130,6 +130,11 @@ class Redis
|
|
130
130
|
node_for(key).expireat(key, unix_time, **kwargs)
|
131
131
|
end
|
132
132
|
|
133
|
+
# Get the expiration for a key as a UNIX timestamp.
|
134
|
+
def expiretime(key)
|
135
|
+
node_for(key).expiretime(key)
|
136
|
+
end
|
137
|
+
|
133
138
|
# Get the time to live (in seconds) for a key.
|
134
139
|
def ttl(key)
|
135
140
|
node_for(key).ttl(key)
|
@@ -145,6 +150,11 @@ class Redis
|
|
145
150
|
node_for(key).pexpireat(key, ms_unix_time, **kwarg)
|
146
151
|
end
|
147
152
|
|
153
|
+
# Get the expiration for a key as number of milliseconds from UNIX Epoch.
|
154
|
+
def pexpiretime(key)
|
155
|
+
node_for(key).pexpiretime(key)
|
156
|
+
end
|
157
|
+
|
148
158
|
# Get the time to live (in milliseconds) for a key.
|
149
159
|
def pttl(key)
|
150
160
|
node_for(key).pttl(key)
|
@@ -370,8 +380,8 @@ class Redis
|
|
370
380
|
end
|
371
381
|
|
372
382
|
# Count the number of set bits in a range of the string value stored at key.
|
373
|
-
def bitcount(key, start = 0, stop = -1)
|
374
|
-
node_for(key).bitcount(key, start, stop)
|
383
|
+
def bitcount(key, start = 0, stop = -1, scale: nil)
|
384
|
+
node_for(key).bitcount(key, start, stop, scale: scale)
|
375
385
|
end
|
376
386
|
|
377
387
|
# Perform a bitwise operation between strings and store the resulting string in a key.
|
@@ -383,8 +393,8 @@ class Redis
|
|
383
393
|
end
|
384
394
|
|
385
395
|
# Return the position of the first bit set to 1 or 0 in a string.
|
386
|
-
def bitpos(key, bit, start = nil, stop = nil)
|
387
|
-
node_for(key).bitpos(key, bit, start, stop)
|
396
|
+
def bitpos(key, bit, start = nil, stop = nil, scale: nil)
|
397
|
+
node_for(key).bitpos(key, bit, start, stop, scale: scale)
|
388
398
|
end
|
389
399
|
|
390
400
|
# Set the string value of a key and return its old value.
|
data/lib/redis/subscribe.rb
CHANGED
@@ -29,6 +29,14 @@ class Redis
|
|
29
29
|
subscription("psubscribe", "punsubscribe", channels, block, timeout)
|
30
30
|
end
|
31
31
|
|
32
|
+
def ssubscribe(*channels, &block)
|
33
|
+
subscription("ssubscribe", "sunsubscribe", channels, block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def ssubscribe_with_timeout(timeout, *channels, &block)
|
37
|
+
subscription("ssubscribe", "sunsubscribe", channels, block, timeout)
|
38
|
+
end
|
39
|
+
|
32
40
|
def unsubscribe(*channels)
|
33
41
|
call_v([:unsubscribe, *channels])
|
34
42
|
end
|
@@ -37,6 +45,10 @@ class Redis
|
|
37
45
|
call_v([:punsubscribe, *channels])
|
38
46
|
end
|
39
47
|
|
48
|
+
def sunsubscribe(*channels)
|
49
|
+
call_v([:sunsubscribe, *channels])
|
50
|
+
end
|
51
|
+
|
40
52
|
def close
|
41
53
|
@client.close
|
42
54
|
end
|
@@ -46,7 +58,11 @@ class Redis
|
|
46
58
|
def subscription(start, stop, channels, block, timeout = 0)
|
47
59
|
sub = Subscription.new(&block)
|
48
60
|
|
49
|
-
|
61
|
+
case start
|
62
|
+
when "ssubscribe" then channels.each { |c| call_v([start, c]) } # avoid cross-slot keys
|
63
|
+
else call_v([start, *channels])
|
64
|
+
end
|
65
|
+
|
50
66
|
while event = @client.next_event(timeout)
|
51
67
|
if event.is_a?(::RedisClient::CommandError)
|
52
68
|
raise Client::ERROR_MAPPING.fetch(event.class), event.message
|
@@ -94,5 +110,17 @@ class Redis
|
|
94
110
|
def pmessage(&block)
|
95
111
|
@callbacks["pmessage"] = block
|
96
112
|
end
|
113
|
+
|
114
|
+
def ssubscribe(&block)
|
115
|
+
@callbacks["ssubscribe"] = block
|
116
|
+
end
|
117
|
+
|
118
|
+
def sunsubscribe(&block)
|
119
|
+
@callbacks["sunsubscribe"] = block
|
120
|
+
end
|
121
|
+
|
122
|
+
def smessage(&block)
|
123
|
+
@callbacks["smessage"] = block
|
124
|
+
end
|
97
125
|
end
|
98
126
|
end
|
data/lib/redis/version.rb
CHANGED
data/lib/redis.rb
CHANGED
@@ -45,7 +45,7 @@ class Redis
|
|
45
45
|
# @option options [String] :host ("127.0.0.1") server hostname
|
46
46
|
# @option options [Integer] :port (6379) server port
|
47
47
|
# @option options [String] :path path to server socket (overrides host and port)
|
48
|
-
# @option options [Float] :timeout (
|
48
|
+
# @option options [Float] :timeout (1.0) timeout in seconds
|
49
49
|
# @option options [Float] :connect_timeout (same as timeout) timeout for initial connect in seconds
|
50
50
|
# @option options [String] :username Username to authenticate against server
|
51
51
|
# @option options [String] :password Password to authenticate against server
|
@@ -137,21 +137,6 @@ class Redis
|
|
137
137
|
end
|
138
138
|
|
139
139
|
if options.key?(:sentinels)
|
140
|
-
if url = options.delete(:url)
|
141
|
-
uri = URI.parse(url)
|
142
|
-
if !options.key?(:name) && uri.host
|
143
|
-
options[:name] = uri.host
|
144
|
-
end
|
145
|
-
|
146
|
-
if !options.key?(:password) && uri.password && !uri.password.empty?
|
147
|
-
options[:password] = uri.password
|
148
|
-
end
|
149
|
-
|
150
|
-
if !options.key?(:username) && uri.user && !uri.user.empty?
|
151
|
-
options[:username] = uri.user
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
140
|
Client.sentinel(**options).new_client
|
156
141
|
else
|
157
142
|
Client.config(**options).new_client
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ezra Zygmuntowicz
|
@@ -16,7 +16,7 @@ authors:
|
|
16
16
|
autorequire:
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
|
-
date:
|
19
|
+
date: 2024-02-09 00:00:00.000000000 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: redis-client
|
@@ -24,14 +24,14 @@ dependencies:
|
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.
|
27
|
+
version: 0.17.0
|
28
28
|
type: :runtime
|
29
29
|
prerelease: false
|
30
30
|
version_requirements: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.17.0
|
35
35
|
description: |2
|
36
36
|
A Ruby client that tries to match Redis' API one-to-one, while still
|
37
37
|
providing an idiomatic interface.
|
@@ -75,9 +75,9 @@ licenses:
|
|
75
75
|
metadata:
|
76
76
|
bug_tracker_uri: https://github.com/redis/redis-rb/issues
|
77
77
|
changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
|
78
|
-
documentation_uri: https://www.rubydoc.info/gems/redis/5.0
|
78
|
+
documentation_uri: https://www.rubydoc.info/gems/redis/5.1.0
|
79
79
|
homepage_uri: https://github.com/redis/redis-rb
|
80
|
-
source_code_uri: https://github.com/redis/redis-rb/tree/v5.0
|
80
|
+
source_code_uri: https://github.com/redis/redis-rb/tree/v5.1.0
|
81
81
|
post_install_message:
|
82
82
|
rdoc_options: []
|
83
83
|
require_paths:
|