redis-client 0.30.1 → 0.31.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c611a453cbb5fecfffcb2b631d0b61a978ad151605d4ff60f8f3cf882358c272
4
- data.tar.gz: 2b91f2484a543961614d9edaa56eefec31528551e8680d3677e1a71a3c4c7f3c
3
+ metadata.gz: a978872b66cb08635b537696d919aa49352de251b9525bc4fa17a25b84801bb3
4
+ data.tar.gz: 2e45ea495c8537bc5a84317d371c4dad00aecf625352eb3893240d8905f20792
5
5
  SHA512:
6
- metadata.gz: 1f69e110f3f3d6775f50e07928650b0bc4bd232ccc2b0186c6579ea9a8fd5bb5e1c40def3d27184c4d30d42faf42e950cbe1c6319d36b8f1f4fb2eaea881ee7f
7
- data.tar.gz: 3919d4e19ab85dababeae0ddf9d476becde0e7ff09e92d2eb18d9c093299fe18454c038835ef43ef09c31b6487d0ee027a0026df1476a9e900860bdb2db646e7
6
+ metadata.gz: 33fc3e223b160391b28528b8555494e64502911826d454c296d3e22293785ce0aa5b7ebe8d52fb1331ed3c5e061788b23f359ddc902fae7c433f83e6988073b1
7
+ data.tar.gz: 9427851d1969f93a46877dc2c3e8fdc024555ecc60adae8ffdabe82879fe1eaa21b96af5cbe98ea6bd366b40dd0ea95fcf20940497ba5d749c13d082ec291972
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.31.0
4
+
5
+ - Improved the Ruby driver buffering logic, should trigger GC less, particularly for large response and when using SSL.
6
+ - `ssl_params` can now be a proc, for environment where SSL certificates frequently change.
7
+ - Raise `RedisClient::ProtocolError` instead of `NoMethodError` when the RESP3 parser hits an unexpected end of stream.
8
+
3
9
  # 0.30.1
4
10
 
5
11
  - hiredis-client: Use `pkg-config` to locate OpenSSL. Should fix compilation issue on precompiled rubies such as the ones from `mise`.
data/README.md CHANGED
@@ -71,7 +71,7 @@ redis.call("GET", "mykey")
71
71
  - `port`: The server port. Defaults to `6379`.
72
72
  - `path`: The path to a UNIX socket, if set `url`, `host` and `port` are ignored.
73
73
  - `ssl`: Whether to connect using SSL or not.
74
- - `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:
74
+ - `ssl_params`: A configuration Hash passed to [`OpenSSL::SSL::SSLContext#set_params`](https://ruby.github.io/openssl/OpenSSL/SSL/SSLContext.html#method-i-set_params), notable options include:
75
75
  - `cert`: The path to the client certificate (e.g. `client.crt`).
76
76
  - `key`: The path to the client key (e.g. `client.key`).
77
77
  - `ca_file`: The certificate authority to use, useful for self-signed certificates (e.g. `ca.crt`),
@@ -65,6 +65,8 @@ class RedisClient
65
65
  def refresh_state
66
66
  now = RedisClient.now
67
67
  @lock.synchronize do
68
+ return unless @state == :open
69
+
68
70
  if @errors.last < (now - @error_timeout)
69
71
  if @success_threshold > 0
70
72
  @state = :half_open
@@ -190,7 +190,7 @@ class RedisClient
190
190
 
191
191
  def ssl_context
192
192
  if ssl
193
- @ssl_context ||= @driver.ssl_context(@ssl_params || {})
193
+ @driver.ssl_context(@ssl_params || {})
194
194
  end
195
195
  end
196
196
 
@@ -71,7 +71,8 @@ class RedisClient
71
71
  result._set_retry_attempt(@retry_attempt)
72
72
 
73
73
  last_error&._set_next_error(result)
74
- first_error ||= last_error = result
74
+ first_error ||= result
75
+ last_error = result
75
76
  end
76
77
 
77
78
  results[index] = result
@@ -76,7 +76,7 @@ class RedisClient
76
76
  private
77
77
 
78
78
  def pool
79
- @pool ||= @mutex.synchronize { new_pool }
79
+ @pool || @mutex.synchronize { @pool ||= new_pool }
80
80
  end
81
81
 
82
82
  def new_pool
@@ -193,12 +193,17 @@ class RedisClient
193
193
  buffer_size = @buffer.bytesize
194
194
  start = @offset - buffer_size
195
195
  empty_buffer = start >= 0
196
+ read_buffer = nil
196
197
 
197
198
  loop do
198
199
  bytes = if empty_buffer
199
200
  @io.read_nonblock([remaining, @chunk_size].max, @buffer, exception: false)
200
201
  else
201
- @io.read_nonblock([remaining, @chunk_size].max, exception: false)
202
+ # We're most likely reading 4kiB or more, hence the read buffer will never be
203
+ # embedded on any recent Ruby implementation, hence we can provide an empty
204
+ # buffer, Ruby will take care of preallocating the required memory.
205
+ read_buffer ||= "".b
206
+ @io.read_nonblock([remaining, @chunk_size].max, read_buffer, exception: false)
202
207
  end
203
208
 
204
209
  case bytes
@@ -233,7 +238,10 @@ class RedisClient
233
238
  @buffer << bytes.force_encoding(ENCODING)
234
239
  end
235
240
  remaining -= bytes.bytesize
236
- return if !strict || remaining <= 0
241
+ if !strict || remaining <= 0
242
+ read_buffer&.clear
243
+ return
244
+ end
237
245
  end
238
246
  end
239
247
  end
@@ -16,21 +16,6 @@ class RedisClient
16
16
  Integer => :dump_numeric,
17
17
  Float => :dump_numeric,
18
18
  }.freeze
19
- PARSER_TYPES = {
20
- '#' => :parse_boolean,
21
- '$' => :parse_blob,
22
- '+' => :parse_string,
23
- '=' => :parse_verbatim_string,
24
- '-' => :parse_error,
25
- ':' => :parse_integer,
26
- '(' => :parse_integer,
27
- ',' => :parse_double,
28
- '_' => :parse_null,
29
- '*' => :parse_array,
30
- '%' => :parse_map,
31
- '~' => :parse_set,
32
- '>' => :parse_array,
33
- }.transform_keys(&:ord).freeze
34
19
  INTEGER_RANGE = ((((2**64) / 2) * -1)..(((2**64) / 2) - 1)).freeze
35
20
 
36
21
  def dump(command, buffer = nil)
@@ -73,23 +58,6 @@ class RedisClient
73
58
  buffer
74
59
  end
75
60
 
76
- def dump_set(set, buffer)
77
- buffer << '~' << set.size.to_s << EOL
78
- set.each do |item|
79
- dump_any(item, buffer)
80
- end
81
- buffer
82
- end
83
-
84
- def dump_hash(hash, buffer)
85
- buffer << '%' << hash.size.to_s << EOL
86
- hash.each_pair do |key, value|
87
- dump_any(key, buffer)
88
- dump_any(value, buffer)
89
- end
90
- buffer
91
- end
92
-
93
61
  def dump_numeric(numeric, buffer)
94
62
  dump_string(numeric.to_s, buffer)
95
63
  end
@@ -137,6 +105,8 @@ class RedisClient
137
105
  parse_set(io)
138
106
  elsif type == 62 # '>'.ord
139
107
  parse_array(io)
108
+ elsif type.nil?
109
+ raise SyntaxError, "Unexpected end of stream"
140
110
  else
141
111
  raise UnknownType, "Unknown sigil type: #{type.chr.inspect}"
142
112
  end
@@ -179,10 +149,6 @@ class RedisClient
179
149
  hash
180
150
  end
181
151
 
182
- def parse_push(io)
183
- parse_array(io)
184
- end
185
-
186
152
  def parse_sequence(io, size)
187
153
  return if size < 0 # RESP2 nil
188
154
 
@@ -28,12 +28,6 @@ class RedisClient
28
28
 
29
29
  context = OpenSSL::SSL::SSLContext.new
30
30
  context.set_params(params)
31
- if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
32
- if context.respond_to?(:verify_hostname) # Missing on JRuby
33
- context.verify_hostname
34
- end
35
- end
36
-
37
31
  context
38
32
  end
39
33
  end
@@ -157,8 +151,9 @@ class RedisClient
157
151
  )
158
152
  true
159
153
  rescue SystemCallError, IOError, OpenSSL::SSL::SSLError, SocketError => error
160
- socket&.close
161
154
  raise CannotConnectError, error.message, error.backtrace
155
+ ensure
156
+ socket&.to_io&.close unless defined?(@io) && @io
162
157
  end
163
158
 
164
159
  KEEP_ALIVE_INTERVAL = 15 # Same as hiredis defaults
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RedisClient
4
- VERSION = "0.30.1"
4
+ VERSION = "0.31.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.1
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
@@ -71,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  requirements: []
74
- rubygems_version: 4.0.12
74
+ rubygems_version: 4.0.20
75
75
  specification_version: 4
76
76
  summary: Simple low-level client for Redis 6+
77
77
  test_files: []