redis-cluster 1.0.0 → 1.0.1.pre.rc.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 328dcd9bbc349a36b70a5f91bc16c69345bef62c
4
- data.tar.gz: 32720a7f55ac9b912878eaf3a287bb940000f461
2
+ SHA256:
3
+ metadata.gz: 9f8427709e6b67eaf1266d6e330dfc37958fbb10dc0ab3845ee97a14319466ce
4
+ data.tar.gz: f26b971ccc78221ef3a3a1c6da1207e71d8b594d3c955ee529743abea5fb4c08
5
5
  SHA512:
6
- metadata.gz: 7e35a19038dfac92f8c0968f44bf442a9eb225b324d2a066aed1aa83e110ea840582113cbda262e0c6323ccaac955eb6f8921b85585d8c91f602adba1913d863
7
- data.tar.gz: 182e883b1fc704db0f1d8e2737fe9a1cc87209d37bf53dc2976f917d427d0ccf4cf400fcb7e7338119ec9e351aa8ed6aa7e62a909a5a209a4aa330a971e6bf98
6
+ metadata.gz: bc342af53829102b0da2108ca999ca74473d62e54adeb3238e898f1e899a4510d5785b07c838b22a282dce5c65e59a8187f34cc3fc6595957dc36289d4595778
7
+ data.tar.gz: 95221ec6964ab2aac0c639a4da59a0f501489e97ad5e27eb27be5f61a5c5158d96ae7c425eb9145b9360df06bd198b8510d96e8cbd2ed1226109ee98300bd6c9
@@ -134,7 +134,7 @@ class RedisCluster
134
134
  cluster.reset if err == :moved
135
135
  asking = err == :ask
136
136
  client = cluster[url]
137
- rescue LoadingStateError, Redis::CannotConnectError => e
137
+ rescue NodeUnhealthyError, Redis::CannotConnectError => e
138
138
  if e.is_a?(Redis::CannotConnectError)
139
139
  asking = false
140
140
  cluster.reset
@@ -198,11 +198,11 @@ class RedisCluster
198
198
  end
199
199
 
200
200
  [leftover, error]
201
- rescue LoadingStateError, Redis::CannotConnectError => e
201
+ rescue NodeUnhealthyError, Redis::CannotConnectError => e
202
202
  # reset url and asking when connection refused
203
203
  futures.each{ |f| f.url = nil; f.asking = false }
204
204
 
205
- [futures, e.is_a?(LoadingStateError) ? :loading : :down]
205
+ [futures, e.is_a?(NodeUnhealthyError) ? :loading : :down]
206
206
  end
207
207
 
208
208
  def scan_reply(reply)
@@ -6,7 +6,7 @@ require_relative 'version'
6
6
 
7
7
  class RedisCluster
8
8
 
9
- class LoadingStateError < StandardError; end
9
+ class NodeUnhealthyError < StandardError; end
10
10
 
11
11
  # Client is a decorator object for Redis::Client. It add queue to support pipelining and another
12
12
  # useful addition
@@ -52,7 +52,7 @@ class RedisCluster
52
52
  end
53
53
  end
54
54
 
55
- def healthy
55
+ def healthy?
56
56
  return true if @healthy
57
57
 
58
58
  # ban for 60 seconds for unhealthy state
@@ -74,7 +74,7 @@ class RedisCluster
74
74
  queue.size.times do |i|
75
75
  result[i] = client.read
76
76
 
77
- unhealthy! if result[i].is_a?(Redis::CommandError) && result[i].message['LOADING']
77
+ unhealthy!(result[i]) if error?(result[i])
78
78
  end
79
79
  end
80
80
 
@@ -83,10 +83,17 @@ class RedisCluster
83
83
  @queue = []
84
84
  end
85
85
 
86
- def unhealthy!
86
+ def unhealthy!(cause)
87
87
  @healthy = false
88
88
  @ban_from = Time.now
89
- raise LoadingStateError
89
+
90
+ error = NodeUnhealthyError.new("Node #{@url} is unhealthy: #{cause}")
91
+ error.set_backtrace(cause.backtrace)
92
+ raise error
93
+ end
94
+
95
+ def error?(res)
96
+ res.is_a?(Redis::CommandError) && (res.message['LOADING'] || res.message['CLUSTERDOWN'])
90
97
  end
91
98
  end
92
99
  end
@@ -16,7 +16,10 @@ class RedisCluster
16
16
  @slots = []
17
17
  @clients = {}
18
18
  @replicas = nil
19
- @client_creater = block
19
+ @client_creater = block || proc do |url|
20
+ host, port = url.split(':', 2)
21
+ Client.new(host: host, port: port)
22
+ end
20
23
 
21
24
  @buffer = []
22
25
  init_client(seeds)
@@ -30,6 +33,10 @@ class RedisCluster
30
33
  options[:read_mode] || :master
31
34
  end
32
35
 
36
+ def logger
37
+ options[:logger]
38
+ end
39
+
33
40
  def slot_for(keys)
34
41
  slot = [keys].flatten.map{ |k| _slot_for(k) }.uniq
35
42
  slot.size == 1 ? slot.first : (raise CROSSSLOT_ERROR)
@@ -67,7 +74,6 @@ class RedisCluster
67
74
  client = random
68
75
  slots_and_clients(client)
69
76
  rescue StandardError => e
70
- clients.delete(client.url)
71
77
  try.positive? ? retry : (raise e)
72
78
  end
73
79
  end
@@ -83,20 +89,18 @@ class RedisCluster
83
89
  private
84
90
 
85
91
  def pick_client(pool, skip: 0)
86
- unhealthy_count = 0
92
+ buff_len = 0
87
93
 
88
94
  (skip...pool.length).each do |i|
89
- if pool[i].healthy
90
- @buffer[i - skip] = pool[i]
91
- else
92
- unhealthy_count += 1
93
- end
95
+ next unless pool[i].healthy?
96
+
97
+ @buffer[buff_len] = pool[i]
98
+ buff_len += 1
94
99
  end
95
100
 
96
- buffer_length = pool.length - skip - unhealthy_count
97
- return nil if buffer_length.zero?
101
+ return nil if buff_len.zero?
98
102
 
99
- i = rand(buffer_length)
103
+ i = rand(buff_len)
100
104
  @buffer[i]
101
105
  end
102
106
 
@@ -118,7 +122,11 @@ class RedisCluster
118
122
  arr[2..-1].each_with_index do |a, i|
119
123
  cli = self["#{a[0]}:#{a[1]}"]
120
124
  replicas[arr[0]] << cli
121
- cli.call([:readonly]) if i.nonzero?
125
+ begin
126
+ cli.call([:readonly]) if i.nonzero?
127
+ rescue NodeUnhealthyError => e
128
+ logger&.error(e)
129
+ end
122
130
  end
123
131
 
124
132
  (arr[0]..arr[1]).each do |slot|
@@ -149,12 +157,7 @@ class RedisCluster
149
157
  end
150
158
 
151
159
  def create_client(url)
152
- if client_creater
153
- client_creater.call(url)
154
- else
155
- host, port = url.split(':', 2)
156
- Client.new(host: host, port: port)
157
- end
160
+ client_creater.call(url)
158
161
  end
159
162
 
160
163
  # -----------------------------------------------------------------------------
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RedisCluster
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1-rc.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1.pre.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bukalapak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-17 00:00:00.000000000 Z
11
+ date: 2018-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -61,12 +61,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
61
  version: '0'
62
62
  required_rubygems_version: !ruby/object:Gem::Requirement
63
63
  requirements:
64
- - - ">="
64
+ - - ">"
65
65
  - !ruby/object:Gem::Version
66
- version: '0'
66
+ version: 1.3.1
67
67
  requirements: []
68
68
  rubyforge_project:
69
- rubygems_version: 2.5.1
69
+ rubygems_version: 2.7.7
70
70
  signing_key:
71
71
  specification_version: 4
72
72
  summary: Redis cluster client. Support pipelining.