redis-client 0.22.2 → 0.25.1
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 +30 -0
- data/README.md +5 -4
- data/lib/redis_client/circuit_breaker.rb +2 -2
- data/lib/redis_client/config.rb +36 -34
- data/lib/redis_client/ruby_connection.rb +9 -4
- data/lib/redis_client/sentinel_config.rb +6 -1
- data/lib/redis_client/version.rb +1 -1
- data/lib/redis_client.rb +29 -2
- metadata +3 -11
- data/Gemfile +0 -22
- data/Gemfile.lock +0 -72
- data/Rakefile +0 -126
- data/redis-client.gemspec +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aec9020863506adfc7189ff46791f9e9a656ca9c4efd042d60b6d9d7eecbbc2
|
4
|
+
data.tar.gz: 821d677e9cec0280ae9e982b78e7aa3116063f58d08f4f446c56bb8fdfeabcd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39b8dd6d1c19c96f30dbc5f8391105037507704954a273d17ab8e25ace88a77ee3504038a8b595a2845b1657f79cffdd76143b34e3b67e01339654c1310c2b41
|
7
|
+
data.tar.gz: 76b6500bf41a318ad3a71088dd3382c16039b2713adced7f511e67c45107e37ef7e1a286b19c10bc18f93292696c1cad8a51b705c930c3bb2d1784b8c67aadfe
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 0.25.1
|
4
|
+
|
5
|
+
- Fix Ruby driver TCP keep alive TTL. It was intended to be 120 seconds but was mistakenly set to 15 seconds.
|
6
|
+
|
7
|
+
# 0.25.0
|
8
|
+
|
9
|
+
- Fix `hiredis-client` compilation with GCC 15.
|
10
|
+
- Fix `hiredis-client` from a work directory with spaces.
|
11
|
+
- Add `CommandError#code`.
|
12
|
+
- Add `RedisClient::NoScriptError` for `EVALSHA`.
|
13
|
+
|
14
|
+
# 0.24.0
|
15
|
+
|
16
|
+
- Allow `sentinel_password` to be provided as a `Proc`.
|
17
|
+
- Ensure `Config#inspect` and `Config#to_s` do not display stored passwords.
|
18
|
+
|
19
|
+
# 0.23.2
|
20
|
+
|
21
|
+
- Fix retry logic not to attempt to retry on an open circuit breaker. Fix #227.
|
22
|
+
|
23
|
+
# 0.23.1
|
24
|
+
|
25
|
+
- Fix a potential crash in `hiredis-client` when using subcriptions (`next_event`). See #221.
|
26
|
+
|
27
|
+
# 0.23.0
|
28
|
+
|
29
|
+
- Allow `password` to be a callable. Makes it easy to implement short lived password authentication strategies.
|
30
|
+
- Fix a thread safety issue in `hiredis-client` when using the `pubsub` client concurrently.
|
31
|
+
|
3
32
|
# 0.22.2
|
4
33
|
|
5
34
|
- Fix the sentinel client to properly extend timeout for blocking commands.
|
@@ -62,6 +91,7 @@
|
|
62
91
|
- Discard sockets rather than explictly close them when a fork is detected. #126.
|
63
92
|
- Allow to configure sentinel client via url. #117.
|
64
93
|
- Fix sentinel to preverse the auth/password when refreshing the sentinel list. #107.
|
94
|
+
- Added `RedisClient#measure_round_trip_delay` method. #113.
|
65
95
|
|
66
96
|
# 0.14.1
|
67
97
|
|
data/README.md
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# RedisClient
|
2
2
|
|
3
|
-
`redis-client` is a simple, low-level, client for Redis 6
|
3
|
+
`redis-client` is a simple, low-level, client for [Redis](https://redis.io/) 6+, [Valkey](https://valkey.io/) 7+, [KeyDB](https://docs.keydb.dev/),
|
4
|
+
and several other databases that implement the same `RESP3` protocol.
|
4
5
|
|
5
6
|
Contrary to the `redis` gem, `redis-client` doesn't try to map all Redis commands to Ruby constructs,
|
6
|
-
it merely is a thin wrapper on top of the RESP3 protocol.
|
7
|
+
it merely is a thin wrapper on top of the `RESP3` protocol.
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
|
@@ -77,7 +78,7 @@ redis.call("GET", "mykey")
|
|
77
78
|
- `db`: The database to select after connecting, defaults to `0`.
|
78
79
|
- `id` ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME`.
|
79
80
|
- `username` Username to authenticate against server, defaults to `"default"`.
|
80
|
-
- `password` Password to authenticate against server.
|
81
|
+
- `password` Password to authenticate against server. Can either be a String or a callable that recieve `username` as argument and return a passowrd as a String.
|
81
82
|
- `timeout`: The general timeout in seconds, default to `1.0`.
|
82
83
|
- `connect_timeout`: The connection timeout, takes precedence over the general timeout when connecting to the server.
|
83
84
|
- `read_timeout`: The read timeout, takes precedence over the general timeout when reading responses from the server.
|
@@ -89,7 +90,7 @@ redis.call("GET", "mykey")
|
|
89
90
|
|
90
91
|
### Sentinel support
|
91
92
|
|
92
|
-
The client is able to perform automatic failover by using [Redis Sentinel](https://redis.io/docs/
|
93
|
+
The client is able to perform automatic failover by using [Redis Sentinel](https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/).
|
93
94
|
|
94
95
|
To connect using Sentinel, use:
|
95
96
|
|
@@ -63,7 +63,7 @@ class RedisClient
|
|
63
63
|
private
|
64
64
|
|
65
65
|
def refresh_state
|
66
|
-
now =
|
66
|
+
now = RedisClient.now
|
67
67
|
@lock.synchronize do
|
68
68
|
if @errors.last < (now - @error_timeout)
|
69
69
|
if @success_threshold > 0
|
@@ -78,7 +78,7 @@ class RedisClient
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def record_error
|
81
|
-
now =
|
81
|
+
now = RedisClient.now
|
82
82
|
expiry = now - @error_timeout
|
83
83
|
@lock.synchronize do
|
84
84
|
if @state == :closed
|
data/lib/redis_client/config.rb
CHANGED
@@ -12,8 +12,8 @@ class RedisClient
|
|
12
12
|
DEFAULT_DB = 0
|
13
13
|
|
14
14
|
module Common
|
15
|
-
attr_reader :db, :
|
16
|
-
:connect_timeout, :read_timeout, :write_timeout, :driver, :
|
15
|
+
attr_reader :db, :id, :ssl, :ssl_params, :command_builder, :inherit_socket,
|
16
|
+
:connect_timeout, :read_timeout, :write_timeout, :driver, :protocol,
|
17
17
|
:middlewares_stack, :custom, :circuit_breaker
|
18
18
|
|
19
19
|
alias_method :ssl?, :ssl
|
@@ -40,7 +40,7 @@ class RedisClient
|
|
40
40
|
circuit_breaker: nil
|
41
41
|
)
|
42
42
|
@username = username
|
43
|
-
@password = password
|
43
|
+
@password = password && !password.respond_to?(:call) ? ->(_) { password } : password
|
44
44
|
@db = begin
|
45
45
|
Integer(db || DEFAULT_DB)
|
46
46
|
rescue ArgumentError
|
@@ -70,7 +70,6 @@ class RedisClient
|
|
70
70
|
|
71
71
|
reconnect_attempts = Array.new(reconnect_attempts, 0).freeze if reconnect_attempts.is_a?(Integer)
|
72
72
|
@reconnect_attempts = reconnect_attempts
|
73
|
-
@connection_prelude = build_connection_prelude
|
74
73
|
|
75
74
|
circuit_breaker = CircuitBreaker.new(**circuit_breaker) if circuit_breaker.is_a?(Hash)
|
76
75
|
if @circuit_breaker = circuit_breaker
|
@@ -87,6 +86,39 @@ class RedisClient
|
|
87
86
|
@middlewares_stack = middlewares_stack
|
88
87
|
end
|
89
88
|
|
89
|
+
def connection_prelude
|
90
|
+
prelude = []
|
91
|
+
pass = password
|
92
|
+
if protocol == 3
|
93
|
+
prelude << if pass
|
94
|
+
["HELLO", "3", "AUTH", username, pass]
|
95
|
+
else
|
96
|
+
["HELLO", "3"]
|
97
|
+
end
|
98
|
+
elsif pass
|
99
|
+
prelude << if @username && !@username.empty?
|
100
|
+
["AUTH", @username, pass]
|
101
|
+
else
|
102
|
+
["AUTH", pass]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if @db && @db != 0
|
107
|
+
prelude << ["SELECT", @db.to_s]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Deep freeze all the strings and commands
|
111
|
+
prelude.map! do |commands|
|
112
|
+
commands = commands.map { |str| str.frozen? ? str : str.dup.freeze }
|
113
|
+
commands.freeze
|
114
|
+
end
|
115
|
+
prelude.freeze
|
116
|
+
end
|
117
|
+
|
118
|
+
def password
|
119
|
+
@password&.call(username)
|
120
|
+
end
|
121
|
+
|
90
122
|
def username
|
91
123
|
@username || DEFAULT_USERNAME
|
92
124
|
end
|
@@ -146,36 +178,6 @@ class RedisClient
|
|
146
178
|
end
|
147
179
|
url
|
148
180
|
end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def build_connection_prelude
|
153
|
-
prelude = []
|
154
|
-
if protocol == 3
|
155
|
-
prelude << if @password
|
156
|
-
["HELLO", "3", "AUTH", @username || DEFAULT_USERNAME, @password]
|
157
|
-
else
|
158
|
-
["HELLO", "3"]
|
159
|
-
end
|
160
|
-
elsif @password
|
161
|
-
prelude << if @username && !@username.empty?
|
162
|
-
["AUTH", @username, @password]
|
163
|
-
else
|
164
|
-
["AUTH", @password]
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
if @db && @db != 0
|
169
|
-
prelude << ["SELECT", @db.to_s]
|
170
|
-
end
|
171
|
-
|
172
|
-
# Deep freeze all the strings and commands
|
173
|
-
prelude.map! do |commands|
|
174
|
-
commands = commands.map { |str| str.frozen? ? str : str.dup.freeze }
|
175
|
-
commands.freeze
|
176
|
-
end
|
177
|
-
prelude.freeze
|
178
|
-
end
|
179
181
|
end
|
180
182
|
|
181
183
|
include Common
|
@@ -104,9 +104,9 @@ class RedisClient
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def measure_round_trip_delay
|
107
|
-
start =
|
107
|
+
start = RedisClient.now_ms
|
108
108
|
call(["PING"], @read_timeout)
|
109
|
-
|
109
|
+
RedisClient.now_ms - start
|
110
110
|
end
|
111
111
|
|
112
112
|
private
|
@@ -116,7 +116,12 @@ class RedisClient
|
|
116
116
|
UNIXSocket.new(@config.path)
|
117
117
|
else
|
118
118
|
sock = if SUPPORTS_RESOLV_TIMEOUT
|
119
|
-
|
119
|
+
begin
|
120
|
+
Socket.tcp(@config.host, @config.port, connect_timeout: @connect_timeout, resolv_timeout: @connect_timeout)
|
121
|
+
rescue Errno::ETIMEDOUT => timeout_error
|
122
|
+
timeout_error.message << ": #{@connect_timeout}s"
|
123
|
+
raise
|
124
|
+
end
|
120
125
|
else
|
121
126
|
Socket.tcp(@config.host, @config.port, connect_timeout: @connect_timeout)
|
122
127
|
end
|
@@ -164,7 +169,7 @@ class RedisClient
|
|
164
169
|
if %i[SOL_TCP SOL_SOCKET TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT].all? { |c| Socket.const_defined? c } # Linux
|
165
170
|
def enable_socket_keep_alive(socket)
|
166
171
|
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
167
|
-
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE,
|
172
|
+
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, KEEP_ALIVE_TTL)
|
168
173
|
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, KEEP_ALIVE_INTERVAL)
|
169
174
|
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT, KEEP_ALIVE_PROBES)
|
170
175
|
end
|
@@ -38,9 +38,14 @@ class RedisClient
|
|
38
38
|
end
|
39
39
|
|
40
40
|
@to_list_of_hash = @to_hash = nil
|
41
|
+
password = if sentinel_password && !sentinel_password.respond_to?(:call)
|
42
|
+
->(_) { sentinel_password }
|
43
|
+
else
|
44
|
+
sentinel_password
|
45
|
+
end
|
41
46
|
@extra_config = {
|
42
47
|
username: sentinel_username,
|
43
|
-
password:
|
48
|
+
password: password,
|
44
49
|
db: nil,
|
45
50
|
}
|
46
51
|
if client_config[:protocol] == 2
|
data/lib/redis_client/version.rb
CHANGED
data/lib/redis_client.rb
CHANGED
@@ -45,6 +45,14 @@ class RedisClient
|
|
45
45
|
def default_driver=(name)
|
46
46
|
@default_driver = driver(name)
|
47
47
|
end
|
48
|
+
|
49
|
+
def now
|
50
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
51
|
+
end
|
52
|
+
|
53
|
+
def now_ms
|
54
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
55
|
+
end
|
48
56
|
end
|
49
57
|
|
50
58
|
register_driver :ruby do
|
@@ -122,8 +130,18 @@ class RedisClient
|
|
122
130
|
end
|
123
131
|
end
|
124
132
|
|
133
|
+
module HasCode
|
134
|
+
attr_reader :code
|
135
|
+
|
136
|
+
def initialize(message = nil, code = nil)
|
137
|
+
super(message)
|
138
|
+
@code = code
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
125
142
|
class CommandError < Error
|
126
143
|
include HasCommand
|
144
|
+
include HasCode
|
127
145
|
|
128
146
|
class << self
|
129
147
|
def parse(error_message)
|
@@ -136,7 +154,7 @@ class RedisClient
|
|
136
154
|
end
|
137
155
|
code ||= error_message.split(' ', 2).first
|
138
156
|
klass = ERRORS.fetch(code, self)
|
139
|
-
klass.new(error_message.strip)
|
157
|
+
klass.new(error_message.strip, code.freeze)
|
140
158
|
end
|
141
159
|
end
|
142
160
|
end
|
@@ -145,12 +163,15 @@ class RedisClient
|
|
145
163
|
PermissionError = Class.new(CommandError)
|
146
164
|
WrongTypeError = Class.new(CommandError)
|
147
165
|
OutOfMemoryError = Class.new(CommandError)
|
166
|
+
NoScriptError = Class.new(CommandError)
|
148
167
|
|
149
168
|
ReadOnlyError = Class.new(ConnectionError)
|
150
169
|
ReadOnlyError.include(HasCommand)
|
170
|
+
ReadOnlyError.include(HasCode)
|
151
171
|
|
152
172
|
MasterDownError = Class.new(ConnectionError)
|
153
173
|
MasterDownError.include(HasCommand)
|
174
|
+
MasterDownError.include(HasCode)
|
154
175
|
|
155
176
|
CommandError::ERRORS = {
|
156
177
|
"WRONGPASS" => AuthenticationError,
|
@@ -159,6 +180,7 @@ class RedisClient
|
|
159
180
|
"MASTERDOWN" => MasterDownError,
|
160
181
|
"WRONGTYPE" => WrongTypeError,
|
161
182
|
"OOM" => OutOfMemoryError,
|
183
|
+
"NOSCRIPT" => NoScriptError,
|
162
184
|
}.freeze
|
163
185
|
|
164
186
|
class << self
|
@@ -702,9 +724,14 @@ class RedisClient
|
|
702
724
|
end
|
703
725
|
rescue ConnectionError, ProtocolError => error
|
704
726
|
preferred_error ||= error
|
705
|
-
preferred_error = error unless error.is_a?(CircuitBreaker::OpenCircuitError)
|
706
727
|
close
|
707
728
|
|
729
|
+
if error.is_a?(CircuitBreaker::OpenCircuitError)
|
730
|
+
raise preferred_error
|
731
|
+
else
|
732
|
+
preferred_error = error
|
733
|
+
end
|
734
|
+
|
708
735
|
if !@disable_reconnection && config.retry_connecting?(tries, error)
|
709
736
|
tries += 1
|
710
737
|
retry
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.25.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-07-15 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: connection_pool
|
@@ -24,7 +23,6 @@ dependencies:
|
|
24
23
|
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: '0'
|
27
|
-
description:
|
28
26
|
email:
|
29
27
|
- jean.boussier@gmail.com
|
30
28
|
executables: []
|
@@ -32,11 +30,8 @@ extensions: []
|
|
32
30
|
extra_rdoc_files: []
|
33
31
|
files:
|
34
32
|
- CHANGELOG.md
|
35
|
-
- Gemfile
|
36
|
-
- Gemfile.lock
|
37
33
|
- LICENSE.md
|
38
34
|
- README.md
|
39
|
-
- Rakefile
|
40
35
|
- lib/redis-client.rb
|
41
36
|
- lib/redis_client.rb
|
42
37
|
- lib/redis_client/circuit_breaker.rb
|
@@ -53,7 +48,6 @@ files:
|
|
53
48
|
- lib/redis_client/sentinel_config.rb
|
54
49
|
- lib/redis_client/url_config.rb
|
55
50
|
- lib/redis_client/version.rb
|
56
|
-
- redis-client.gemspec
|
57
51
|
homepage: https://github.com/redis-rb/redis-client
|
58
52
|
licenses:
|
59
53
|
- MIT
|
@@ -62,7 +56,6 @@ metadata:
|
|
62
56
|
homepage_uri: https://github.com/redis-rb/redis-client
|
63
57
|
source_code_uri: https://github.com/redis-rb/redis-client
|
64
58
|
changelog_uri: https://github.com/redis-rb/redis-client/blob/master/CHANGELOG.md
|
65
|
-
post_install_message:
|
66
59
|
rdoc_options: []
|
67
60
|
require_paths:
|
68
61
|
- lib
|
@@ -77,8 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
70
|
- !ruby/object:Gem::Version
|
78
71
|
version: '0'
|
79
72
|
requirements: []
|
80
|
-
rubygems_version: 3.
|
81
|
-
signing_key:
|
73
|
+
rubygems_version: 3.6.2
|
82
74
|
specification_version: 4
|
83
75
|
summary: Simple low-level client for Redis 6+
|
84
76
|
test_files: []
|
data/Gemfile
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
# Specify your gem's dependencies in redis-client.gemspec
|
6
|
-
gemspec name: "redis-client"
|
7
|
-
|
8
|
-
gem "minitest"
|
9
|
-
gem "rake", "~> 13.2"
|
10
|
-
gem "rake-compiler"
|
11
|
-
gem "rubocop"
|
12
|
-
gem "rubocop-minitest"
|
13
|
-
gem "toxiproxy"
|
14
|
-
|
15
|
-
group :benchmark do
|
16
|
-
gem "benchmark-ips"
|
17
|
-
gem "hiredis"
|
18
|
-
gem "redis", "~> 4.6"
|
19
|
-
gem "stackprof", platform: :mri
|
20
|
-
end
|
21
|
-
|
22
|
-
gem "byebug", platform: :mri
|
data/Gemfile.lock
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
redis-client (0.22.2)
|
5
|
-
connection_pool
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
ast (2.4.2)
|
11
|
-
benchmark-ips (2.13.0)
|
12
|
-
byebug (11.1.3)
|
13
|
-
connection_pool (2.4.1)
|
14
|
-
hiredis (0.6.3)
|
15
|
-
hiredis (0.6.3-java)
|
16
|
-
json (2.7.1)
|
17
|
-
json (2.7.1-java)
|
18
|
-
minitest (5.23.0)
|
19
|
-
parallel (1.24.0)
|
20
|
-
parser (3.3.0.5)
|
21
|
-
ast (~> 2.4.1)
|
22
|
-
racc
|
23
|
-
racc (1.7.3)
|
24
|
-
racc (1.7.3-java)
|
25
|
-
rainbow (3.1.1)
|
26
|
-
rake (13.2.1)
|
27
|
-
rake-compiler (1.2.7)
|
28
|
-
rake
|
29
|
-
redis (4.6.0)
|
30
|
-
regexp_parser (2.9.0)
|
31
|
-
rexml (3.2.6)
|
32
|
-
rubocop (1.50.2)
|
33
|
-
json (~> 2.3)
|
34
|
-
parallel (~> 1.10)
|
35
|
-
parser (>= 3.2.0.0)
|
36
|
-
rainbow (>= 2.2.2, < 4.0)
|
37
|
-
regexp_parser (>= 1.8, < 3.0)
|
38
|
-
rexml (>= 3.2.5, < 4.0)
|
39
|
-
rubocop-ast (>= 1.28.0, < 2.0)
|
40
|
-
ruby-progressbar (~> 1.7)
|
41
|
-
unicode-display_width (>= 2.4.0, < 3.0)
|
42
|
-
rubocop-ast (1.30.0)
|
43
|
-
parser (>= 3.2.1.0)
|
44
|
-
rubocop-minitest (0.30.0)
|
45
|
-
rubocop (>= 1.39, < 2.0)
|
46
|
-
ruby-progressbar (1.13.0)
|
47
|
-
stackprof (0.2.26)
|
48
|
-
toxiproxy (2.0.2)
|
49
|
-
unicode-display_width (2.5.0)
|
50
|
-
|
51
|
-
PLATFORMS
|
52
|
-
ruby
|
53
|
-
universal-java-18
|
54
|
-
x86_64-darwin-20
|
55
|
-
x86_64-linux
|
56
|
-
|
57
|
-
DEPENDENCIES
|
58
|
-
benchmark-ips
|
59
|
-
byebug
|
60
|
-
hiredis
|
61
|
-
minitest
|
62
|
-
rake (~> 13.2)
|
63
|
-
rake-compiler
|
64
|
-
redis (~> 4.6)
|
65
|
-
redis-client!
|
66
|
-
rubocop
|
67
|
-
rubocop-minitest
|
68
|
-
stackprof
|
69
|
-
toxiproxy
|
70
|
-
|
71
|
-
BUNDLED WITH
|
72
|
-
2.3.13
|
data/Rakefile
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rake/extensiontask"
|
4
|
-
require "rake/testtask"
|
5
|
-
require 'rubocop/rake_task'
|
6
|
-
|
7
|
-
RuboCop::RakeTask.new
|
8
|
-
|
9
|
-
require "rake/clean"
|
10
|
-
CLOBBER.include "pkg"
|
11
|
-
require "bundler/gem_helper"
|
12
|
-
Bundler::GemHelper.install_tasks(name: "redis-client")
|
13
|
-
Bundler::GemHelper.install_tasks(dir: "hiredis-client", name: "hiredis-client")
|
14
|
-
|
15
|
-
gemspec = Gem::Specification.load("redis-client.gemspec")
|
16
|
-
Rake::ExtensionTask.new do |ext|
|
17
|
-
ext.name = "hiredis_connection"
|
18
|
-
ext.ext_dir = "hiredis-client/ext/redis_client/hiredis"
|
19
|
-
ext.lib_dir = "hiredis-client/lib/redis_client"
|
20
|
-
ext.gem_spec = gemspec
|
21
|
-
CLEAN.add("#{ext.ext_dir}/vendor/*.{a,o}")
|
22
|
-
end
|
23
|
-
|
24
|
-
namespace :test do
|
25
|
-
Rake::TestTask.new(:ruby) do |t|
|
26
|
-
t.libs << "test"
|
27
|
-
t.libs << "lib"
|
28
|
-
t.test_files = FileList["test/**/*_test.rb"].exclude("test/sentinel/*_test.rb")
|
29
|
-
t.options = '-v' if ENV['CI'] || ENV['VERBOSE']
|
30
|
-
end
|
31
|
-
|
32
|
-
Rake::TestTask.new(:sentinel) do |t|
|
33
|
-
t.libs << "test/sentinel"
|
34
|
-
t.libs << "test"
|
35
|
-
t.libs << "lib"
|
36
|
-
t.test_files = FileList["test/sentinel/*_test.rb"]
|
37
|
-
t.options = '-v' if ENV['CI'] || ENV['VERBOSE']
|
38
|
-
end
|
39
|
-
|
40
|
-
Rake::TestTask.new(:hiredis) do |t|
|
41
|
-
t.libs << "test/hiredis"
|
42
|
-
t.libs << "test"
|
43
|
-
t.libs << "hiredis-client/lib"
|
44
|
-
t.libs << "lib"
|
45
|
-
t.test_files = FileList["test/**/*_test.rb"].exclude("test/sentinel/*_test.rb")
|
46
|
-
t.options = '-v' if ENV['CI'] || ENV['VERBOSE']
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
hiredis_supported = RUBY_ENGINE == "ruby" && !RUBY_PLATFORM.match?(/mswin/)
|
51
|
-
if hiredis_supported
|
52
|
-
task test: %i[test:ruby test:hiredis test:sentinel]
|
53
|
-
else
|
54
|
-
task test: %i[test:ruby test:sentinel]
|
55
|
-
end
|
56
|
-
|
57
|
-
namespace :hiredis do
|
58
|
-
task :download do
|
59
|
-
version = "1.0.2"
|
60
|
-
archive_path = "tmp/hiredis-#{version}.tar.gz"
|
61
|
-
url = "https://github.com/redis/hiredis/archive/refs/tags/v#{version}.tar.gz"
|
62
|
-
system("curl", "-L", url, out: archive_path) or raise "Downloading of #{url} failed"
|
63
|
-
system("rm", "-rf", "hiredis-client/ext/redis_client/hiredis/vendor/")
|
64
|
-
system("mkdir", "-p", "hiredis-client/ext/redis_client/hiredis/vendor/")
|
65
|
-
system(
|
66
|
-
"tar", "xvzf", archive_path,
|
67
|
-
"-C", "hiredis-client/ext/redis_client/hiredis/vendor",
|
68
|
-
"--strip-components", "1",
|
69
|
-
)
|
70
|
-
system("rm", "-rf", "hiredis-client/ext/redis_client/hiredis/vendor/examples")
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
benchmark_suites = %w(single pipelined drivers)
|
75
|
-
benchmark_modes = %i[ruby yjit hiredis]
|
76
|
-
namespace :benchmark do
|
77
|
-
benchmark_suites.each do |suite|
|
78
|
-
benchmark_modes.each do |mode|
|
79
|
-
next if suite == "drivers" && mode == :hiredis
|
80
|
-
|
81
|
-
name = "#{suite}_#{mode}"
|
82
|
-
desc name
|
83
|
-
task name do
|
84
|
-
output_path = "benchmark/#{name}.md"
|
85
|
-
sh "rm", "-f", output_path
|
86
|
-
File.open(output_path, "w+") do |output|
|
87
|
-
output.puts("ruby: `#{RUBY_DESCRIPTION}`\n\n")
|
88
|
-
output.puts("redis-server: `#{`redis-server -v`.strip}`\n\n")
|
89
|
-
output.puts
|
90
|
-
output.flush
|
91
|
-
env = {}
|
92
|
-
args = []
|
93
|
-
args << "--yjit" if mode == :yjit
|
94
|
-
env["DRIVER"] = mode == :hiredis ? "hiredis" : "ruby"
|
95
|
-
system(env, RbConfig.ruby, *args, "benchmark/#{suite}.rb", out: output)
|
96
|
-
end
|
97
|
-
|
98
|
-
skipping = false
|
99
|
-
output = File.readlines(output_path).reject do |line|
|
100
|
-
if skipping
|
101
|
-
if line == "Comparison:\n"
|
102
|
-
skipping = false
|
103
|
-
true
|
104
|
-
else
|
105
|
-
skipping
|
106
|
-
end
|
107
|
-
else
|
108
|
-
skipping = true if line.start_with?("Warming up ---")
|
109
|
-
skipping
|
110
|
-
end
|
111
|
-
end
|
112
|
-
File.write(output_path, output.join)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
task all: benchmark_suites.flat_map { |s| benchmark_modes.flat_map { |m| "#{s}_#{m}" } }
|
118
|
-
end
|
119
|
-
|
120
|
-
if hiredis_supported
|
121
|
-
task default: %i[compile test rubocop]
|
122
|
-
task ci: %i[compile test:ruby test:hiredis]
|
123
|
-
else
|
124
|
-
task default: %i[test rubocop]
|
125
|
-
task ci: %i[test:ruby]
|
126
|
-
end
|
data/redis-client.gemspec
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/redis_client/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "redis-client"
|
7
|
-
spec.version = RedisClient::VERSION
|
8
|
-
spec.authors = ["Jean Boussier"]
|
9
|
-
spec.email = ["jean.boussier@gmail.com"]
|
10
|
-
|
11
|
-
spec.summary = "Simple low-level client for Redis 6+"
|
12
|
-
spec.homepage = "https://github.com/redis-rb/redis-client"
|
13
|
-
spec.license = "MIT"
|
14
|
-
spec.required_ruby_version = ">= 2.6.0"
|
15
|
-
|
16
|
-
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
-
|
18
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
-
spec.metadata["changelog_uri"] = File.join(spec.homepage, "blob/master/CHANGELOG.md")
|
21
|
-
|
22
|
-
# Specify which files should be added to the gem when it is released.
|
23
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
26
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|hiredis-client|test|spec|features|benchmark)/|\.(?:git|rubocop))})
|
27
|
-
end
|
28
|
-
end
|
29
|
-
spec.require_paths = ["lib"]
|
30
|
-
|
31
|
-
spec.add_runtime_dependency "connection_pool"
|
32
|
-
end
|