redis-client 0.1.0 → 0.3.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: d53aaf68e8bf2bc7160a8b708d86c40d13a229a2bfa88734ada0ae03839d6330
4
- data.tar.gz: 7ebc1e2e488dbd0bc7895db4714237e893408f017222922cc94faec4b7646e7c
3
+ metadata.gz: '097ad5acec4f5ea01788629c3fe2c606e54c1a2a0749c4e489487cf6bd446eae'
4
+ data.tar.gz: 275d778806cb7848d99ddcba33f1e932853efc9f0d149d6409692d1b39452d86
5
5
  SHA512:
6
- metadata.gz: 397746e753c9c44e6b6f7d046b9e8cb389c25c7a8d8dea40e7ab81c099f328d4f34c1d77d7c2c66c0ea7b12056f282a76c3dc5a700b1acee49b89cddc509070d
7
- data.tar.gz: a2fcda7b8bbef1a0988fcd7434306da5769dbcf1ad91b5f790186646eedd1b21fa289b044bacd3f3b91486f8d06e73c51d608f92662bcb366e3d3e871a138b40
6
+ metadata.gz: c553d706fe8b955a0c6b65a28e9d6a1ddcdec156a562ec5092396a0bca9fa72a251441b8675484fff2d4db3d8e2f335043d226bb4c9c3359e84acc9b7605543f
7
+ data.tar.gz: 68dcc5d81b1632dd60d22651d0ef600903fe607230d3ac396d5e98aab7694d374d5e577777234d7e514fc4df04b332e0fdb31b3c9971fb116c6b0e87c1ddc5f5
data/.rubocop.yml CHANGED
@@ -7,6 +7,7 @@ Layout/LineLength:
7
7
  Max: 120
8
8
  Exclude:
9
9
  - 'test/**/*'
10
+ - 'benchmark/**/*'
10
11
 
11
12
  Layout/CaseIndentation:
12
13
  EnforcedStyle: end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # Unreleased
2
+
3
+ # 0.3.0
4
+
5
+ - `hiredis` is now the default driver when available.
6
+ - Add `RedisClient.default_driver=`.
7
+ - `#call` now takes an optional block to cast the return value.
8
+ - Treat `#call` keyword arguments as Redis flags.
9
+ - Fix `RedisClient#multi` returning some errors as values instead of raising them.
10
+
11
+ # 0.2.1
12
+
13
+ - Use a more robust way to detect the current compiler.
14
+
15
+ # 0.2.0
16
+ - Added `RedisClient.register` as a public instrumentation API.
17
+ - Fix `read_timeout=` and `write_timeout=` to apply even when the client or pool is already connected.
18
+ - Properly convert DNS resolution errors into `RedisClient::ConnectionError`. Previously it would raise `SocketError`
19
+
1
20
  # 0.1.0
2
21
 
3
22
  - Initial Release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redis-client (0.0.0)
4
+ redis-client (0.3.0)
5
5
  connection_pool
6
6
 
7
7
  GEM
@@ -64,4 +64,4 @@ DEPENDENCIES
64
64
  toxiproxy
65
65
 
66
66
  BUNDLED WITH
67
- 2.3.8
67
+ 2.3.13
data/README.md CHANGED
@@ -145,19 +145,68 @@ redis.call("LPUSH", "list", "1", "2", "3", "4")
145
145
  Hashes are flatenned as well:
146
146
 
147
147
  ```ruby
148
- redis.call("HMSET", "hash", foo: 1, bar: 2)
149
- redis.call("SET", "key", "value", ex: 5)
148
+ redis.call("HMSET", "hash", { "foo" => "1", "bar" => "2" })
150
149
  ```
151
150
 
152
151
  is equivalent to:
153
152
 
154
153
  ```ruby
155
154
  redis.call("HMSET", "hash", "foo", "1", "bar", "2")
156
- redis.call("SET", "key", "value", "ex", "5")
157
155
  ```
158
156
 
159
157
  Any other type requires the caller to explictly cast the argument as a string.
160
158
 
159
+ Keywords arguments are treated as Redis command flags:
160
+
161
+ ```ruby
162
+ redis.call("SET", "mykey", "value", nx: true, ex: 60)
163
+ redis.call("SET", "mykey", "value", nx: false, ex: nil)
164
+ ```
165
+
166
+ is equivalent to:
167
+
168
+ ```ruby
169
+ redis.call("SET", "mykey", "value", "nx", "ex", "60")
170
+ redis.call("SET", "mykey", "value")
171
+ ```
172
+
173
+ If flags are built dynamically, you'll have to explictly pass them as keyword arguments with `**`:
174
+
175
+ ```ruby
176
+ flags = {}
177
+ flags[:nx] = true if something?
178
+ redis.call("SET", "mykey", "value", **flags)
179
+ ```
180
+
181
+ **Important Note**: because of the keyword argument semantic change between Ruby 2 and Ruby 3,
182
+ unclosed hash literals with string keys may be interpreted differently:
183
+
184
+ ```ruby
185
+ redis.call("HMSET", "hash", "foo" => "bar")
186
+ ```
187
+
188
+ On Ruby 2 `"foo" => "bar"` will be passed as a postional argument, but on Ruby 3 it will be interpreted as keyword
189
+ arguments. To avoid such problem, make sure to enclose hash literals:
190
+
191
+ ```ruby
192
+ redis.call("HMSET", "hash", { "foo" => "bar" })
193
+ ```
194
+
195
+ ### Commands return values
196
+
197
+ Contrary to the `redis` gem, `redis-client` doesn't do any type casting on the return value of commands.
198
+
199
+ If you wish to cast the return value, you can pass a block to the `#call` familly of methods:
200
+
201
+ ```ruby
202
+ redis.call("INCR", "counter") # => 1
203
+ redis.call("GET", "counter") # => "1"
204
+ redis.call("GET", "counter", &:to_i) # => 1
205
+
206
+ redis.call("EXISTS", "counter") # => 1
207
+ redis.call("EXISTS", "counter") { |c| c > 0 } # => true
208
+ ```
209
+
161
210
  ### Blocking commands
162
211
 
163
212
  For blocking commands such as `BRPOP`, a custom timeout duration can be passed as first argument of the `#blocking_call` method:
@@ -270,6 +319,25 @@ end
270
319
 
271
320
  ## Production
272
321
 
322
+ ### Instrumentation
323
+
324
+ `redis-client` offers a public instrumentation API monitoring tools.
325
+
326
+ ```ruby
327
+ module MyRedisInstrumentation
328
+ def call(command, redis_config)
329
+ MyMonitoringService.instrument("redis.query") { super }
330
+ end
331
+
332
+ def call_pipelined(commands, redis_config)
333
+ MyMonitoringService.instrument("redis.pipeline") { super }
334
+ end
335
+ end
336
+ RedisClient.register(MyRedisInstrumentation)
337
+ ```
338
+
339
+ Note that this instrumentation is global.
340
+
273
341
  ### Timeouts
274
342
 
275
343
  The client allows you to configure connect, read, and write timeouts.
@@ -319,6 +387,24 @@ redis.call("GET", "counter") # Will be retried up to 3 times.
319
387
  redis.call_once("INCR", "counter") # Won't be retried.
320
388
  ```
321
389
 
390
+ ### Drivers
391
+
392
+ `redis-client` ships with two connection implementations, a `hiredis` binding and a pure Ruby implementation.
393
+
394
+ The hiredis binding is only available on Linux, macOS and other POSIX platforms. When available it is the default.
395
+
396
+ The default driver can be set through `RedisClient.default_driver=`:
397
+
398
+ ```ruby
399
+ RedisClient.default_driver = :ruby
400
+ ```
401
+
402
+ You can also select the driver on a per connection basis:
403
+
404
+ ```ruby
405
+ redis_config = RedisClient.config(driver: :ruby, ...)
406
+ ```
407
+
322
408
  ## Notable differences with the `redis` gem
323
409
 
324
410
  ### Thread Safety
data/Rakefile CHANGED
@@ -19,7 +19,16 @@ end
19
19
  Rake::TestTask.new(:test) do |t|
20
20
  t.libs << "test"
21
21
  t.libs << "lib"
22
- t.test_files = FileList["test/**/*_test.rb"]
22
+ t.test_files = FileList["test/**/*_test.rb"].exclude("test/sentinel/*_test.rb")
23
+ end
24
+
25
+ namespace :test do
26
+ Rake::TestTask.new(:sentinel) do |t|
27
+ t.libs << "test/sentinel"
28
+ t.libs << "test"
29
+ t.libs << "lib"
30
+ t.test_files = FileList["test/sentinel/*_test.rb"]
31
+ end
23
32
  end
24
33
 
25
34
  namespace :hiredis do
@@ -49,7 +58,7 @@ namespace :benchmark do
49
58
  env = {}
50
59
  args = []
51
60
  args << "--yjit" if mode == :yjit
52
- env["DRIVER"] = "hiredis" if mode == :hiredis
61
+ env["DRIVER"] = mode == :hiredis ? "hiredis" : "ruby"
53
62
  system(env, RbConfig.ruby, *args, "benchmark/#{suite}.rb", out: output)
54
63
  end
55
64
 
@@ -74,13 +83,13 @@ namespace :benchmark do
74
83
  end
75
84
 
76
85
  if RUBY_PLATFORM == "java"
77
- task default: %i[test rubocop]
86
+ task default: %i[test test:sentinel rubocop]
78
87
  else
79
- task default: %i[compile test rubocop]
88
+ task default: %i[compile test test:sentinel rubocop]
80
89
  end
81
90
 
82
91
  if ENV["DRIVER"] == "hiredis"
83
- task ci: %i[compile test]
92
+ task ci: %i[compile test test:sentinel]
84
93
  else
85
- task ci: %i[test]
94
+ task ci: %i[test test:sentinel]
86
95
  end
@@ -0,0 +1,2 @@
1
+ _Init_hiredis_connection
2
+ _ruby_abi_version
@@ -0,0 +1,7 @@
1
+ hiredis_connection_1.0 {
2
+ global:
3
+ Init_hiredis_connection;
4
+ ruby_abi_version;
5
+ local:
6
+ *;
7
+ };
@@ -2,13 +2,13 @@
2
2
 
3
3
  require "mkmf"
4
4
 
5
- if RUBY_ENGINE == "ruby"
5
+ if RUBY_ENGINE == "ruby" && !RUBY_ENGINE.match?(/mswin/)
6
+ have_func("rb_hash_new_capa", "ruby.h")
7
+
6
8
  hiredis_dir = File.expand_path('vendor', __dir__)
7
9
 
8
10
  make_program = with_config("make-prog", ENV["MAKE"])
9
11
  make_program ||= case RUBY_PLATFORM
10
- when /mswin/
11
- 'nmake'
12
12
  when /(bsd|solaris)/
13
13
  'gmake'
14
14
  else
@@ -31,18 +31,33 @@ if RUBY_ENGINE == "ruby"
31
31
  end
32
32
 
33
33
  Dir.chdir(hiredis_dir) do
34
- flags = %(CFLAGS="-I#{openssl_include}" SSL_LDFLAGS="-L#{openssl_lib}") if openssl_lib
35
- success = system("#{make_program} static USE_SSL=1 #{flags}")
36
- raise "Building hiredis failed" unless success
34
+ flags = ["static", "USE_SSL=1"]
35
+ if openssl_lib
36
+ flags << %(CFLAGS="-I#{openssl_include}") << %(SSL_LDFLAGS="-L#{openssl_lib}")
37
+ end
38
+
39
+ flags << "OPTIMIZATION=-g" if ENV["EXT_PEDANTIC"]
40
+
41
+ unless system(make_program, *flags)
42
+ raise "Building hiredis failed"
43
+ end
37
44
  end
38
45
 
39
46
  $CFLAGS << " -I#{hiredis_dir}"
40
- $LDFLAGS << " #{hiredis_dir}/libhiredis.a #{hiredis_dir}/libhiredis_ssl.a -lssl -lcrypto"
41
- $CFLAGS << " -O3"
47
+ $LDFLAGS << " -lssl -lcrypto"
48
+ $libs << " #{hiredis_dir}/libhiredis.a #{hiredis_dir}/libhiredis_ssl.a "
42
49
  $CFLAGS << " -std=c99 "
43
-
44
50
  if ENV["EXT_PEDANTIC"]
45
51
  $CFLAGS << " -Werror"
52
+ $CFLAGS << " -g "
53
+ else
54
+ $CFLAGS << " -O3 "
55
+ end
56
+
57
+ if `cc --version`.match?(/ clang /i) || RbConfig::CONFIG['CC'].match?(/clang/i)
58
+ $LDFLAGS << ' -Wl,-exported_symbols_list,"' << File.join(__dir__, 'export.clang') << '"'
59
+ elsif RbConfig::CONFIG['CC'].match?(/gcc/i)
60
+ $LDFLAGS << ' -Wl,--version-script="' << File.join(__dir__, 'export.gcc') << '"'
46
61
  end
47
62
 
48
63
  $CFLAGS << " -Wno-declaration-after-statement" # Older compilers
@@ -38,6 +38,13 @@
38
38
  #include "hiredis.h"
39
39
  #include "hiredis_ssl.h"
40
40
 
41
+ #if !defined(HAVE_RB_HASH_NEW_CAPA)
42
+ static inline VALUE rb_hash_new_capa(long capa)
43
+ {
44
+ return rb_hash_new();
45
+ }
46
+ #endif
47
+
41
48
  static VALUE rb_cSet, rb_eRedisClientCommandError, rb_eRedisClientConnectionError;
42
49
  static VALUE rb_eRedisClientConnectTimeoutError, rb_eRedisClientReadTimeoutError, rb_eRedisClientWriteTimeoutError;
43
50
  static ID id_parse, id_add, id_new;
@@ -148,6 +155,10 @@ static void *reply_create_string(const redisReadTask *task, char *cstr, size_t l
148
155
  rb_enc_associate(string, rb_ascii8bit_encoding());
149
156
  }
150
157
 
158
+ if (task->type == REDIS_REPLY_STATUS) {
159
+ rb_str_freeze(string);
160
+ }
161
+
151
162
  if (task->type == REDIS_REPLY_ERROR) {
152
163
  string = rb_funcall(rb_eRedisClientCommandError, id_parse, 1, string);
153
164
  }
@@ -162,7 +173,7 @@ static void *reply_create_array(const redisReadTask *task, size_t elements) {
162
173
  value = rb_ary_new_capa(elements);
163
174
  break;
164
175
  case REDIS_REPLY_MAP:
165
- value = rb_hash_new();
176
+ value = rb_hash_new_capa(elements / 2);
166
177
  break;
167
178
  case REDIS_REPLY_SET:
168
179
  value = rb_funcallv(rb_cSet, id_new, 0, NULL);
@@ -428,6 +439,7 @@ static VALUE hiredis_connect_finish(hiredis_connection_t *connection, redisConte
428
439
 
429
440
  /* Check for socket error */
430
441
  if (getsockopt(context->fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) {
442
+ context->err = REDIS_ERR_IO;
431
443
  redis_raise_error_and_disconnect(context, rb_eRedisClientConnectTimeoutError);
432
444
  }
433
445
 
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RedisClient
4
+ module CommandBuilder
5
+ extend self
6
+
7
+ if Symbol.method_defined?(:name)
8
+ def generate!(args, kwargs)
9
+ command = args.flat_map do |element|
10
+ case element
11
+ when Hash
12
+ element.flatten
13
+ when Set
14
+ element.to_a
15
+ else
16
+ element
17
+ end
18
+ end
19
+
20
+ kwargs.each do |key, value|
21
+ if value
22
+ if value == true
23
+ command << key.name
24
+ else
25
+ command << key.name << value
26
+ end
27
+ end
28
+ end
29
+
30
+ command.map! do |element|
31
+ case element
32
+ when String
33
+ element
34
+ when Symbol
35
+ element.name
36
+ when Integer, Float
37
+ element.to_s
38
+ else
39
+ raise TypeError, "Unsupported command argument type: #{element.class}"
40
+ end
41
+ end
42
+
43
+ command
44
+ end
45
+ else
46
+ def generate!(args, kwargs)
47
+ command = args.flat_map do |element|
48
+ case element
49
+ when Hash
50
+ element.flatten
51
+ when Set
52
+ element.to_a
53
+ else
54
+ element
55
+ end
56
+ end
57
+
58
+ kwargs.each do |key, value|
59
+ if value
60
+ if value == true
61
+ command << key.to_s
62
+ else
63
+ command << key.to_s << value
64
+ end
65
+ end
66
+ end
67
+
68
+ command.map! do |element|
69
+ case element
70
+ when String
71
+ element
72
+ when Integer, Float, Symbol
73
+ element.to_s
74
+ else
75
+ raise TypeError, "Unsupported command argument type: #{element.class}"
76
+ end
77
+ end
78
+
79
+ command
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "openssl"
3
4
  require "uri"
4
5
 
5
6
  class RedisClient
@@ -11,7 +12,7 @@ class RedisClient
11
12
  DEFAULT_DB = 0
12
13
 
13
14
  module Common
14
- attr_reader :db, :username, :password, :id, :ssl, :ssl_params,
15
+ attr_reader :db, :username, :password, :id, :ssl, :ssl_params, :command_builder,
15
16
  :connect_timeout, :read_timeout, :write_timeout, :driver, :connection_prelude
16
17
 
17
18
  alias_method :ssl?, :ssl
@@ -27,7 +28,8 @@ class RedisClient
27
28
  connect_timeout: timeout,
28
29
  ssl: nil,
29
30
  ssl_params: nil,
30
- driver: :ruby,
31
+ driver: nil,
32
+ command_builder: CommandBuilder,
31
33
  reconnect_attempts: false
32
34
  )
33
35
  @username = username || DEFAULT_USERNAME
@@ -41,17 +43,9 @@ class RedisClient
41
43
  @read_timeout = read_timeout
42
44
  @write_timeout = write_timeout
43
45
 
44
- @driver = case driver
45
- when :ruby
46
- Connection
47
- when :hiredis
48
- unless defined?(RedisClient::HiredisConnection)
49
- require "redis_client/hiredis_connection"
50
- end
51
- HiredisConnection
52
- else
53
- raise ArgumentError, "Unknown driver #{driver.inspect}, expected one of: `:ruby`, `:hiredis`"
54
- end
46
+ @driver = driver ? RedisClient.driver(driver) : RedisClient.default_driver
47
+
48
+ @command_builder = command_builder
55
49
 
56
50
  reconnect_attempts = Array.new(reconnect_attempts, 0).freeze if reconnect_attempts.is_a?(Integer)
57
51
  @reconnect_attempts = reconnect_attempts
@@ -84,41 +78,8 @@ class RedisClient
84
78
  false
85
79
  end
86
80
 
87
- def hiredis_ssl_context
88
- @hiredis_ssl_context ||= HiredisConnection::SSLContext.new(
89
- ca_file: @ssl_params[:ca_file],
90
- ca_path: @ssl_params[:ca_path],
91
- cert: @ssl_params[:cert],
92
- key: @ssl_params[:key],
93
- hostname: @ssl_params[:hostname],
94
- )
95
- end
96
-
97
- def openssl_context
98
- @openssl_context ||= begin
99
- params = @ssl_params.dup || {}
100
-
101
- cert = params[:cert]
102
- if cert.is_a?(String)
103
- cert = File.read(cert) if File.exist?(cert)
104
- params[:cert] = OpenSSL::X509::Certificate.new(cert)
105
- end
106
-
107
- key = params[:key]
108
- if key.is_a?(String)
109
- key = File.read(key) if File.exist?(key)
110
- params[:key] = OpenSSL::PKey.read(key)
111
- end
112
-
113
- context = OpenSSL::SSL::SSLContext.new
114
- context.set_params(params)
115
- if context.verify_mode != OpenSSL::SSL::VERIFY_NONE
116
- if context.respond_to?(:verify_hostname) # Missing on JRuby
117
- context.verify_hostname
118
- end
119
- end
120
- context
121
- end
81
+ def ssl_context
82
+ @ssl_context ||= @driver.ssl_context(@ssl_params)
122
83
  end
123
84
 
124
85
  private
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RedisClient
4
+ module ConnectionMixin
5
+ def call(command, timeout)
6
+ write(command)
7
+ result = read(timeout)
8
+ if result.is_a?(CommandError)
9
+ raise result
10
+ else
11
+ result
12
+ end
13
+ end
14
+
15
+ def call_pipelined(commands, timeouts)
16
+ exception = nil
17
+
18
+ size = commands.size
19
+ results = Array.new(commands.size)
20
+ write_multi(commands)
21
+
22
+ size.times do |index|
23
+ timeout = timeouts && timeouts[index]
24
+ result = read(timeout)
25
+ if result.is_a?(CommandError)
26
+ exception ||= result
27
+ end
28
+ results[index] = result
29
+ end
30
+
31
+ if exception
32
+ raise exception
33
+ else
34
+ results
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RedisClient
4
+ module Decorator
5
+ class << self
6
+ def create(commands_mixin)
7
+ client_decorator = Class.new(Client)
8
+ client_decorator.include(commands_mixin)
9
+
10
+ pipeline_decorator = Class.new(Pipeline)
11
+ pipeline_decorator.include(commands_mixin)
12
+ client_decorator.const_set(:Pipeline, pipeline_decorator)
13
+
14
+ client_decorator
15
+ end
16
+ end
17
+
18
+ module CommandsMixin
19
+ def initialize(client)
20
+ @client = client
21
+ end
22
+
23
+ %i(call call_once blocking_call).each do |method|
24
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
25
+ def #{method}(*args, &block)
26
+ @client.#{method}(*args, &block)
27
+ end
28
+ ruby2_keywords :#{method} if respond_to?(:ruby2_keywords, true)
29
+ RUBY
30
+ end
31
+ end
32
+
33
+ class Pipeline
34
+ include CommandsMixin
35
+ end
36
+
37
+ class Client
38
+ include CommandsMixin
39
+
40
+ def initialize(_client)
41
+ super
42
+ @_pipeline_class = self.class::Pipeline
43
+ end
44
+
45
+ def with(*args)
46
+ @client.with(*args) { |c| yield self.class.new(c) }
47
+ end
48
+ ruby2_keywords :with if respond_to?(:ruby2_keywords, true)
49
+
50
+ def pipelined
51
+ @client.pipelined { |p| yield @_pipeline_class.new(p) }
52
+ end
53
+
54
+ def multi(**kwargs)
55
+ @client.multi(**kwargs) { |p| yield @_pipeline_class.new(p) }
56
+ end
57
+
58
+ %i(close scan hscan sscan zscan).each do |method|
59
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
60
+ def #{method}(*args, &block)
61
+ @client.#{method}(*args, &block)
62
+ end
63
+ ruby2_keywords :#{method} if respond_to?(:ruby2_keywords, true)
64
+ RUBY
65
+ end
66
+
67
+ %i(id config size connect_timeout read_timeout write_timeout).each do |reader|
68
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
69
+ def #{reader}
70
+ @client.#{reader}
71
+ end
72
+ RUBY
73
+ end
74
+
75
+ %i(timeout connect_timeout read_timeout write_timeout).each do |writer|
76
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
77
+ def #{writer}=(value)
78
+ @client.#{writer} = value
79
+ end
80
+ RUBY
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "redis_client/hiredis_connection.so"
4
+ require "redis_client/connection_mixin"
4
5
 
5
6
  class RedisClient
6
7
  class HiredisConnection
8
+ include ConnectionMixin
9
+
10
+ class << self
11
+ def ssl_context(ssl_params)
12
+ HiredisConnection::SSLContext.new(
13
+ ca_file: ssl_params[:ca_file],
14
+ ca_path: ssl_params[:ca_path],
15
+ cert: ssl_params[:cert],
16
+ key: ssl_params[:key],
17
+ hostname: ssl_params[:hostname],
18
+ )
19
+ end
20
+ end
21
+
7
22
  class SSLContext
8
23
  def initialize(ca_file: nil, ca_path: nil, cert: nil, key: nil, hostname: nil)
9
24
  if (error = init(ca_file, ca_path, cert, key, hostname))
@@ -24,7 +39,7 @@ class RedisClient
24
39
  end
25
40
 
26
41
  if config.ssl
27
- init_ssl(config.hiredis_ssl_context)
42
+ init_ssl(config.ssl_context)
28
43
  end
29
44
  end
30
45
 
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RedisClient
4
+ module Middlewares
5
+ extend self
6
+
7
+ def call(command, _config)
8
+ yield command
9
+ end
10
+ alias_method :call_pipelined, :call
11
+ end
12
+ end