redis-client 0.20.0 → 0.21.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: 154db13231ff43137f013f9ef224846201eabf5fef93059a5ed48206e558f238
4
- data.tar.gz: 882208c7ad423619cc19cdc3c0b9ae02bd75e425bd702e29b1f2104896a4e0cc
3
+ metadata.gz: 4742ae57d2d4b4510921d37359540257a2e70ee0f9038276f40f95506ae2ffa0
4
+ data.tar.gz: cb3f9702abcd04ae46cfb5d59350884fb9bcff6f6d4990f1e6a0ae66fb6a1f4a
5
5
  SHA512:
6
- metadata.gz: 6e3d3fa8d9684387519cdcc90a7c43319678defa957087902fdb2297ada820cbe746c7821126bcfbdc1f35877bb642382c7b5abebd4a227b2b60a24b8944b4f8
7
- data.tar.gz: 40ceb06e68a8fabd9dd067ab177f5e6ca83b9af04e04b8f166bdc36e33ddd642190c400446e029c91b8416eb44f17aeb5cea950b06b7afc2daf6fa5514bef3f3
6
+ metadata.gz: 14212b26415dd02f6b23f2f729b9690bcf9bd06c156b60ffb5cb4b9061172a3c08f670242d2e6d391770c4abb9cfdd3bd79dfd8d039ae54a9e1537ea39dfd05f
7
+ data.tar.gz: d5b1276dffe3c3fb6220fb06b9e22fd1440bd7d83e19e37031019f98b69ab3ae5c13cbef8bcd036e1929008f764d9b5117451c9fcb07964b28d11cad14ac449e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.21.1
4
+
5
+ - Handle unresolved Sentinel master/replica error when displaying server URL in exceptions. See #182.
6
+
7
+ # 0.21.0
8
+
9
+ - Include redis server URL in most error messages. See #178.
10
+ - Close Redis Sentinel connection after resolving role. See #176.
11
+
3
12
  # 0.20.0
4
13
 
5
14
  - Accept `unix://` schemes as well as simple paths in the `url:` config parameter. #170.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redis-client (0.20.0)
4
+ redis-client (0.21.1)
5
5
  connection_pool
6
6
 
7
7
  GEM
@@ -15,7 +15,7 @@ GEM
15
15
  hiredis (0.6.3-java)
16
16
  json (2.7.1)
17
17
  json (2.7.1-java)
18
- minitest (5.22.0)
18
+ minitest (5.22.3)
19
19
  parallel (1.24.0)
20
20
  parser (3.3.0.5)
21
21
  ast (~> 2.4.1)
@@ -91,6 +91,10 @@ class RedisClient
91
91
  @username || DEFAULT_USERNAME
92
92
  end
93
93
 
94
+ def resolved?
95
+ true
96
+ end
97
+
94
98
  def sentinel?
95
99
  false
96
100
  end
@@ -124,10 +128,17 @@ class RedisClient
124
128
 
125
129
  def server_url
126
130
  if path
127
- "#{path}/#{db}"
131
+ url = "unix://#{path}"
132
+ if db != 0
133
+ url = "#{url}?db=#{db}"
134
+ end
128
135
  else
129
- "redis#{'s' if ssl?}://#{host}:#{port}/#{db}"
136
+ url = "redis#{'s' if ssl?}://#{host}:#{port}"
137
+ if db != 0
138
+ url = "#{url}/#{db}"
139
+ end
130
140
  end
141
+ url
131
142
  end
132
143
 
133
144
  private
@@ -32,6 +32,7 @@ class RedisClient
32
32
  @pending_reads -= 1
33
33
  if result.is_a?(Error)
34
34
  result._set_command(command)
35
+ result._set_config(config)
35
36
  raise result
36
37
  else
37
38
  result
@@ -50,10 +51,19 @@ class RedisClient
50
51
  timeout = timeouts && timeouts[index]
51
52
  result = read(timeout)
52
53
  @pending_reads -= 1
53
- if result.is_a?(Error)
54
+
55
+ # A multi/exec command can return an array of results.
56
+ # An error from a multi/exec command is handled in Multi#_coerce!.
57
+ if result.is_a?(Array)
58
+ result.each do |res|
59
+ res._set_config(config) if res.is_a?(Error)
60
+ end
61
+ elsif result.is_a?(Error)
54
62
  result._set_command(commands[index])
63
+ result._set_config(config)
55
64
  exception ||= result
56
65
  end
66
+
57
67
  results[index] = result
58
68
  end
59
69
 
@@ -40,6 +40,8 @@ class RedisClient
40
40
 
41
41
  SUPPORTS_RESOLV_TIMEOUT = Socket.method(:tcp).parameters.any? { |p| p.last == :resolv_timeout }
42
42
 
43
+ attr_reader :config
44
+
43
45
  def initialize(config, connect_timeout:, read_timeout:, write_timeout:)
44
46
  super()
45
47
  @config = config
@@ -72,8 +74,8 @@ class RedisClient
72
74
  buffer = RESP3.dump(command)
73
75
  begin
74
76
  @io.write(buffer)
75
- rescue SystemCallError, IOError => error
76
- raise ConnectionError, error.message
77
+ rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
78
+ raise ConnectionError.with_config(error.message, config)
77
79
  end
78
80
  end
79
81
 
@@ -84,8 +86,8 @@ class RedisClient
84
86
  end
85
87
  begin
86
88
  @io.write(buffer)
87
- rescue SystemCallError, IOError => error
88
- raise ConnectionError, error.message
89
+ rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
90
+ raise ConnectionError.with_config(error.message, config)
89
91
  end
90
92
  end
91
93
 
@@ -96,9 +98,9 @@ class RedisClient
96
98
  @io.with_timeout(timeout) { RESP3.load(@io) }
97
99
  end
98
100
  rescue RedisClient::RESP3::UnknownType => error
99
- raise RedisClient::ProtocolError, error.message
101
+ raise RedisClient::ProtocolError.with_config(error.message, config)
100
102
  rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
101
- raise ConnectionError, error.message
103
+ raise ConnectionError.with_config(error.message, config)
102
104
  end
103
105
 
104
106
  def measure_round_trip_delay
@@ -130,9 +132,9 @@ class RedisClient
130
132
  loop do
131
133
  case status = socket.connect_nonblock(exception: false)
132
134
  when :wait_readable
133
- socket.to_io.wait_readable(@connect_timeout) or raise CannotConnectError
135
+ socket.to_io.wait_readable(@connect_timeout) or raise CannotConnectError.with_config("", config)
134
136
  when :wait_writable
135
- socket.to_io.wait_writable(@connect_timeout) or raise CannotConnectError
137
+ socket.to_io.wait_writable(@connect_timeout) or raise CannotConnectError.with_config("", config)
136
138
  when socket
137
139
  break
138
140
  else
@@ -112,6 +112,12 @@ class RedisClient
112
112
  end
113
113
  end
114
114
 
115
+ def resolved?
116
+ @mutex.synchronize do
117
+ !!@config
118
+ end
119
+ end
120
+
115
121
  private
116
122
 
117
123
  def sentinels_to_configs(sentinels)
@@ -188,6 +194,10 @@ class RedisClient
188
194
  if success
189
195
  @sentinel_configs.unshift(@sentinel_configs.delete(sentinel_config))
190
196
  end
197
+ # Redis Sentinels may be configured to have a lower maxclients setting than
198
+ # the Redis nodes. Close the connection to the Sentinel node to avoid using
199
+ # a connection.
200
+ sentinel_client.close
191
201
  end
192
202
  end
193
203
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RedisClient
4
- VERSION = "0.20.0"
4
+ VERSION = "0.21.1"
5
5
  end
data/lib/redis_client.rb CHANGED
@@ -77,7 +77,29 @@ class RedisClient
77
77
  end
78
78
  end
79
79
 
80
- Error = Class.new(StandardError)
80
+ module HasConfig
81
+ attr_reader :config
82
+
83
+ def _set_config(config)
84
+ @config = config
85
+ end
86
+
87
+ def message
88
+ return super unless config&.resolved?
89
+
90
+ "#{super} (#{config.server_url})"
91
+ end
92
+ end
93
+
94
+ class Error < StandardError
95
+ include HasConfig
96
+
97
+ def self.with_config(message, config = nil)
98
+ new(message).tap do |error|
99
+ error._set_config(config)
100
+ end
101
+ end
102
+ end
81
103
 
82
104
  ProtocolError = Class.new(Error)
83
105
  UnsupportedServer = Class.new(Error)
@@ -114,7 +136,7 @@ class RedisClient
114
136
  end
115
137
  code ||= error_message.split(' ', 2).first
116
138
  klass = ERRORS.fetch(code, self)
117
- klass.new(error_message)
139
+ klass.new(error_message.strip)
118
140
  end
119
141
  end
120
142
  end
@@ -750,10 +772,13 @@ class RedisClient
750
772
  end
751
773
  end
752
774
  end
753
- rescue FailoverError, CannotConnectError
754
- raise
775
+ rescue FailoverError, CannotConnectError => error
776
+ error._set_config(config)
777
+ raise error
755
778
  rescue ConnectionError => error
756
- raise CannotConnectError, error.message, error.backtrace
779
+ connect_error = CannotConnectError.with_config(error.message, config)
780
+ connect_error.set_backtrace(error.backtrace)
781
+ raise connect_error
757
782
  rescue CommandError => error
758
783
  if error.message.match?(/ERR unknown command ['`]HELLO['`]/)
759
784
  raise UnsupportedServer,
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.20.0
4
+ version: 0.21.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: 2024-02-12 00:00:00.000000000 Z
11
+ date: 2024-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool