redis-client 0.15.0 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa81349f7f830db128f2637bc4c782543b9c51a16075b54fdc4700810a95ae83
4
- data.tar.gz: d34e19d6229292bb6b15e61aebeda57729780040e098f0fae1beb534f9717ff9
3
+ metadata.gz: 3e73c2e13870d3adcb345e544fe99bbffa6ad1bf5f7267203e49f838c56a7492
4
+ data.tar.gz: d090544eb97a93ad0d21d5a6c14c40ffb3ca384425ccf27d82c797f0f7e2d35a
5
5
  SHA512:
6
- metadata.gz: 01ed887cfc90ffc36ff82669a459d1c9b13b72c9d81f66ca770e7642c16cba90d30cfd31768029b81a1519778f6af2905b145ab606f070008ac471192ce812fa
7
- data.tar.gz: 64320bfdcdaa3fd4402ae41350dc0451127f895e3f224d916140ea3fc5813dfe9344f04dc18c20d82e9c3a0878d19ade9b3716274278a21fbe3fd1c5da855797
6
+ metadata.gz: 60e0fbf2c30888ac05855af2ba6b145ac96e0e011cc58d989f66e9379baa549c9af1ad2f7077ce431b334d6b1318b83463eac7bcb7a323752c79644e0dbce495
7
+ data.tar.gz: 1e3e10ef87472a412239261c0642e134f9521e83e49def834bb76b1aa6481c8e8fc9b13cfe1916c0f0ed43af8799a331e9649caa61155ce9eeb8391b0c15c98a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.17.1
4
+
5
+ - Add support for `NaN` in RESP3 protocol doubles.
6
+ This was initially missing from the spec and added about a year ago.
7
+
8
+ # 0.17.0
9
+
10
+ - Adds `sentinel_username` and `sentinel_password` options for `RedisClient#sentinel`
11
+
12
+ # 0.16.0
13
+
14
+ - Add `RedisClient#disable_reconnection`.
15
+ - Reverted the special discard of connection. A regular `close(2)` should be enough.
16
+
3
17
  # 0.15.0
4
18
 
5
19
  - Discard sockets rather than explictly close them when a fork is detected. #126.
@@ -66,7 +80,7 @@
66
80
 
67
81
  - Make the client resilient to `Timeout.timeout` or `Thread#kill` use (it still is very much discouraged to use either).
68
82
  Use of async interrupts could cause responses to be interleaved.
69
- - hiredis: handle commands returning a top-level `false` (no command does this today, but some extensions might).
83
+ - hiredis: handle commands returning a top-level `false` (no command does this today, but some extensions might).
70
84
  - Workaround a bug in Ruby 2.6 causing a crash if the `debug` gem is enabled when `redis-client` is being required. Fix: #48
71
85
 
72
86
  # 0.8.0
@@ -85,7 +99,7 @@
85
99
 
86
100
  - Raise a distinct `RedisClient::OutOfMemoryError`, for Redis `OOM` errors.
87
101
  - Fix the instrumentation API to be called even for authentication commands.
88
- - Fix `url:` configuration to accept a trailing slash.
102
+ - Fix `url:` configuration to accept a trailing slash.
89
103
 
90
104
  # 0.7.1
91
105
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redis-client (0.15.0)
4
+ redis-client (0.17.1)
5
5
  connection_pool
6
6
 
7
7
  GEM
@@ -19,7 +19,7 @@ GEM
19
19
  ast (~> 2.4.1)
20
20
  rainbow (3.1.1)
21
21
  rake (13.0.6)
22
- rake-compiler (1.2.3)
22
+ rake-compiler (1.2.5)
23
23
  rake
24
24
  redis (4.6.0)
25
25
  regexp_parser (2.5.0)
data/README.md CHANGED
@@ -42,7 +42,7 @@ redis.with do |r|
42
42
  end
43
43
  ```
44
44
 
45
- If you are working in a single threaded environment, or wish to use your own connection pooling mechanism,
45
+ If you are working in a single-threaded environment, or wish to use your own connection pooling mechanism,
46
46
  you can obtain a raw client with `#new_client`
47
47
 
48
48
  ```ruby
@@ -67,11 +67,11 @@ redis.call("GET", "mykey")
67
67
  - `host`: The server hostname or IP address. Defaults to `"localhost"`.
68
68
  - `port`: The server port. Defaults to `6379`.
69
69
  - `path`: The path to a UNIX socket, if set `url`, `host` and `port` are ignored.
70
- - `ssl`: Wether to connect using SSL or not.
70
+ - `ssl`: Whether to connect using SSL or not.
71
71
  - `ssl_params`: A configuration Hash passed to [`OpenSSL::SSL::SSLContext#set_params`](https://www.rubydoc.info/stdlib/openssl/OpenSSL%2FSSL%2FSSLContext:set_params), notable options include:
72
72
  - `cert`: The path to the client certificate (e.g. `client.crt`).
73
73
  - `key`: The path to the client key (e.g. `client.key`).
74
- - `ca_file`: The certificate authority to use, useful for self signed certificates (e.g. `ca.crt`),
74
+ - `ca_file`: The certificate authority to use, useful for self-signed certificates (e.g. `ca.crt`),
75
75
  - `db`: The database to select after connecting, defaults to `0`.
76
76
  - `id` ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME`.
77
77
  - `username` Username to authenticate against server, defaults to `"default"`.
@@ -83,7 +83,7 @@ redis.call("GET", "mykey")
83
83
  - `reconnect_attempts`: Specify how many times the client should retry to send queries. Defaults to `0`. Makes sure to read the [reconnection section](#reconnection) before enabling it.
84
84
  - `circuit_breaker`: A Hash with circuit breaker configuration. Defaults to `nil`. See the [circuit breaker section](#circuit-breaker) for details.
85
85
  - `protocol:` The version of the RESP protocol to use. Default to `3`.
86
- - `custom`: A user owned value ignored by `redis-client` but available as `Config#custom`. This can be used to hold middleware configurations and other user specific metadatas.
86
+ - `custom`: A user-owned value ignored by `redis-client` but available as `Config#custom`. This can be used to hold middleware configurations and other user-specific metadata.
87
87
 
88
88
  ### Sentinel support
89
89
 
@@ -128,6 +128,41 @@ but a few so that if one is down the client will try the next one. The client
128
128
  is able to remember the last Sentinel that was able to reply correctly and will
129
129
  use it for the next requests.
130
130
 
131
+ To [authenticate](https://redis.io/docs/management/sentinel/#configuring-sentinel-instances-with-authentication) Sentinel itself, you can specify the `sentinel_username` and `sentinel_password` options per instance. Exclude the `sentinel_username` option if you're using password-only authentication.
132
+
133
+ ```ruby
134
+ SENTINELS = [{ host: '127.0.0.1', port: 26380},
135
+ { host: '127.0.0.1', port: 26381}]
136
+
137
+ redis_config = RedisClient.sentinel(name: 'mymaster', sentinel_username: 'appuser', sentinel_password: 'mysecret', sentinels: SENTINELS, role: :master)
138
+ ```
139
+
140
+ If you specify a username and/or password at the top level for your main Redis instance, Sentinel *will not* using thouse credentials
141
+
142
+ ```ruby
143
+ # Use 'mysecret' to authenticate against the mymaster instance, but skip authentication for the sentinels:
144
+ SENTINELS = [{ host: '127.0.0.1', port: 26380 },
145
+ { host: '127.0.0.1', port: 26381 }]
146
+
147
+ redis_config = RedisClient.sentinel(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret')
148
+ ```
149
+
150
+ So you have to provide Sentinel credential and Redis explictly even they are the same
151
+
152
+ ```ruby
153
+ # Use 'mysecret' to authenticate against the mymaster instance and sentinel
154
+ SENTINELS = [{ host: '127.0.0.1', port: 26380 },
155
+ { host: '127.0.0.1', port: 26381 }]
156
+
157
+ redis_config = RedisClient.sentinel(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret', sentinel_password: 'mysecret')
158
+ ```
159
+
160
+ Also the `name`, `password`, `username` and `db` for Redis instance can be passed as an url:
161
+
162
+ ```ruby
163
+ redis_config = RedisClient.sentinel(url: "redis://appuser:mysecret@mymaster/10", sentinels: SENTINELS, role: :master)
164
+ ```
165
+
131
166
  ### Type support
132
167
 
133
168
  Only a select few Ruby types are supported as arguments beside strings.
@@ -344,7 +379,7 @@ end
344
379
  ```
345
380
 
346
381
  *Note*: pubsub connections are stateful, as such they won't ever reconnect automatically.
347
- The caller is resonsible for reconnecting if the connection is lost and to resubscribe to
382
+ The caller is responsible for reconnecting if the connection is lost and to resubscribe to
348
383
  all channels.
349
384
 
350
385
  ## Production
@@ -380,7 +415,7 @@ redis_config = RedisClient.config(middlewares: [AnotherRedisInstrumentation])
380
415
  redis_config.new_client
381
416
  ```
382
417
 
383
- If middlewares need a client specific configuration, `Config#custom` can be used
418
+ If middlewares need a client-specific configuration, `Config#custom` can be used
384
419
 
385
420
  ```ruby
386
421
  module MyGlobalRedisInstrumentation
@@ -454,9 +489,9 @@ redis_config = RedisClient.config(reconnect_attempts: [0, 0.05, 0.1])
454
489
  ```
455
490
 
456
491
  This configuration is generally used when the Redis server is expected to failover or recover relatively quickly and
457
- that it's not really possibe to continue without issuing the command.
492
+ that it's not really possible to continue without issuing the command.
458
493
 
459
- When the Redis server is used as an ephemeral cache, circuit breakers are generally prefered.
494
+ When the Redis server is used as an ephemeral cache, circuit breakers are generally preferred.
460
495
 
461
496
  ### Circuit Breaker
462
497
 
@@ -159,21 +159,23 @@ class RedisClient
159
159
  host: nil,
160
160
  port: nil,
161
161
  path: nil,
162
+ username: nil,
163
+ password: nil,
162
164
  **kwargs
163
165
  )
164
166
  if url
165
167
  url_config = URLConfig.new(url)
166
168
  kwargs = {
167
169
  ssl: url_config.ssl?,
168
- username: url_config.username,
169
- password: url_config.password,
170
170
  db: url_config.db,
171
171
  }.compact.merge(kwargs)
172
172
  host ||= url_config.host
173
173
  port ||= url_config.port
174
+ username ||= url_config.username
175
+ password ||= url_config.password
174
176
  end
175
177
 
176
- super(**kwargs)
178
+ super(username: username, password: password, **kwargs)
177
179
 
178
180
  @host = host || DEFAULT_HOST
179
181
  @port = Integer(port || DEFAULT_PORT)
@@ -24,10 +24,6 @@ class RedisClient
24
24
  @io.to_io.close
25
25
  end
26
26
 
27
- def reopen(*args)
28
- @io.to_io.reopen(*args)
29
- end
30
-
31
27
  def closed?
32
28
  @io.to_io.closed?
33
29
  end
@@ -175,6 +175,8 @@ class RedisClient
175
175
 
176
176
  def parse_double(io)
177
177
  case value = io.gets_chomp
178
+ when "nan"
179
+ Float::NAN
178
180
  when "inf"
179
181
  Float::INFINITY
180
182
  when "-inf"
@@ -58,13 +58,6 @@ class RedisClient
58
58
  super
59
59
  end
60
60
 
61
- def discard
62
- unless @io.closed?
63
- @io.reopen(File::NULL)
64
- end
65
- close
66
- end
67
-
68
61
  def read_timeout=(timeout)
69
62
  @read_timeout = timeout
70
63
  @io.read_timeout = timeout if @io
@@ -9,8 +9,16 @@ class RedisClient
9
9
 
10
10
  attr_reader :name
11
11
 
12
- def initialize(sentinels:, role: :master, name: nil, url: nil, **client_config)
13
- unless %i(master replica slave).include?(role)
12
+ def initialize(
13
+ sentinels:,
14
+ sentinel_password: nil,
15
+ sentinel_username: nil,
16
+ role: :master,
17
+ name: nil,
18
+ url: nil,
19
+ **client_config
20
+ )
21
+ unless %i(master replica slave).include?(role.to_sym)
14
22
  raise ArgumentError, "Expected role to be either :master or :replica, got: #{role.inspect}"
15
23
  end
16
24
 
@@ -30,7 +38,11 @@ class RedisClient
30
38
  end
31
39
 
32
40
  @to_list_of_hash = @to_hash = nil
33
- @extra_config = {}
41
+ @extra_config = {
42
+ username: sentinel_username,
43
+ password: sentinel_password,
44
+ db: nil,
45
+ }
34
46
  if client_config[:protocol] == 2
35
47
  @extra_config[:protocol] = client_config[:protocol]
36
48
  @to_list_of_hash = lambda do |may_be_a_list|
@@ -43,7 +55,7 @@ class RedisClient
43
55
  end
44
56
 
45
57
  @sentinels = {}.compare_by_identity
46
- @role = role
58
+ @role = role.to_sym
47
59
  @mutex = Mutex.new
48
60
  @config = nil
49
61
 
@@ -106,9 +118,9 @@ class RedisClient
106
118
  sentinels.map do |sentinel|
107
119
  case sentinel
108
120
  when String
109
- Config.new(**@client_config, **@extra_config, url: sentinel, db: nil)
121
+ Config.new(**@client_config, **@extra_config, url: sentinel)
110
122
  else
111
- Config.new(**@client_config, **@extra_config, **sentinel, db: nil)
123
+ Config.new(**@client_config, **@extra_config, **sentinel)
112
124
  end
113
125
  end
114
126
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RedisClient
4
- VERSION = "0.15.0"
4
+ VERSION = "0.17.1"
5
5
  end
data/lib/redis_client.rb CHANGED
@@ -175,6 +175,10 @@ class RedisClient
175
175
  "#<#{self.class.name} #{config.server_url}#{id_string}>"
176
176
  end
177
177
 
178
+ def server_url
179
+ config.server_url
180
+ end
181
+
178
182
  def size
179
183
  1
180
184
  end
@@ -358,9 +362,8 @@ class RedisClient
358
362
  self
359
363
  end
360
364
 
361
- def discard
362
- @raw_connection&.discard
363
- self
365
+ def disable_reconnection(&block)
366
+ ensure_connected(retryable: false, &block)
364
367
  end
365
368
 
366
369
  def pipelined
@@ -623,7 +626,7 @@ class RedisClient
623
626
  end
624
627
 
625
628
  def ensure_connected(retryable: true)
626
- discard if !config.inherit_socket && @pid != PIDCache.pid
629
+ close if !config.inherit_socket && @pid != PIDCache.pid
627
630
 
628
631
  if @disable_reconnection
629
632
  if block_given?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-01 00:00:00.000000000 Z
11
+ date: 2023-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool