redis 3.3.5 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +132 -2
  3. data/README.md +144 -79
  4. data/lib/redis.rb +1174 -405
  5. data/lib/redis/client.rb +150 -90
  6. data/lib/redis/cluster.rb +295 -0
  7. data/lib/redis/cluster/command.rb +81 -0
  8. data/lib/redis/cluster/command_loader.rb +34 -0
  9. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  10. data/lib/redis/cluster/node.rb +107 -0
  11. data/lib/redis/cluster/node_key.rb +31 -0
  12. data/lib/redis/cluster/node_loader.rb +37 -0
  13. data/lib/redis/cluster/option.rb +93 -0
  14. data/lib/redis/cluster/slot.rb +86 -0
  15. data/lib/redis/cluster/slot_loader.rb +49 -0
  16. data/lib/redis/connection.rb +4 -2
  17. data/lib/redis/connection/command_helper.rb +5 -10
  18. data/lib/redis/connection/hiredis.rb +6 -5
  19. data/lib/redis/connection/registry.rb +2 -1
  20. data/lib/redis/connection/ruby.rb +126 -128
  21. data/lib/redis/connection/synchrony.rb +21 -8
  22. data/lib/redis/distributed.rb +147 -72
  23. data/lib/redis/errors.rb +48 -0
  24. data/lib/redis/hash_ring.rb +30 -73
  25. data/lib/redis/pipeline.rb +55 -15
  26. data/lib/redis/subscribe.rb +11 -12
  27. data/lib/redis/version.rb +3 -1
  28. metadata +49 -202
  29. data/.gitignore +0 -16
  30. data/.travis.yml +0 -89
  31. data/.travis/Gemfile +0 -11
  32. data/.yardopts +0 -3
  33. data/Gemfile +0 -4
  34. data/Rakefile +0 -87
  35. data/benchmarking/logging.rb +0 -71
  36. data/benchmarking/pipeline.rb +0 -51
  37. data/benchmarking/speed.rb +0 -21
  38. data/benchmarking/suite.rb +0 -24
  39. data/benchmarking/worker.rb +0 -71
  40. data/examples/basic.rb +0 -15
  41. data/examples/consistency.rb +0 -114
  42. data/examples/dist_redis.rb +0 -43
  43. data/examples/incr-decr.rb +0 -17
  44. data/examples/list.rb +0 -26
  45. data/examples/pubsub.rb +0 -37
  46. data/examples/sentinel.rb +0 -41
  47. data/examples/sentinel/sentinel.conf +0 -9
  48. data/examples/sentinel/start +0 -49
  49. data/examples/sets.rb +0 -36
  50. data/examples/unicorn/config.ru +0 -3
  51. data/examples/unicorn/unicorn.rb +0 -20
  52. data/redis.gemspec +0 -44
  53. data/test/bitpos_test.rb +0 -69
  54. data/test/blocking_commands_test.rb +0 -42
  55. data/test/client_test.rb +0 -59
  56. data/test/command_map_test.rb +0 -30
  57. data/test/commands_on_hashes_test.rb +0 -21
  58. data/test/commands_on_hyper_log_log_test.rb +0 -21
  59. data/test/commands_on_lists_test.rb +0 -20
  60. data/test/commands_on_sets_test.rb +0 -77
  61. data/test/commands_on_sorted_sets_test.rb +0 -137
  62. data/test/commands_on_strings_test.rb +0 -101
  63. data/test/commands_on_value_types_test.rb +0 -133
  64. data/test/connection_handling_test.rb +0 -277
  65. data/test/connection_test.rb +0 -57
  66. data/test/db/.gitkeep +0 -0
  67. data/test/distributed_blocking_commands_test.rb +0 -46
  68. data/test/distributed_commands_on_hashes_test.rb +0 -10
  69. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  70. data/test/distributed_commands_on_lists_test.rb +0 -22
  71. data/test/distributed_commands_on_sets_test.rb +0 -83
  72. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  73. data/test/distributed_commands_on_strings_test.rb +0 -59
  74. data/test/distributed_commands_on_value_types_test.rb +0 -95
  75. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  76. data/test/distributed_connection_handling_test.rb +0 -23
  77. data/test/distributed_internals_test.rb +0 -79
  78. data/test/distributed_key_tags_test.rb +0 -52
  79. data/test/distributed_persistence_control_commands_test.rb +0 -26
  80. data/test/distributed_publish_subscribe_test.rb +0 -92
  81. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  82. data/test/distributed_scripting_test.rb +0 -102
  83. data/test/distributed_sorting_test.rb +0 -20
  84. data/test/distributed_test.rb +0 -58
  85. data/test/distributed_transactions_test.rb +0 -32
  86. data/test/encoding_test.rb +0 -18
  87. data/test/error_replies_test.rb +0 -59
  88. data/test/fork_safety_test.rb +0 -65
  89. data/test/helper.rb +0 -232
  90. data/test/helper_test.rb +0 -24
  91. data/test/internals_test.rb +0 -417
  92. data/test/lint/blocking_commands.rb +0 -150
  93. data/test/lint/hashes.rb +0 -162
  94. data/test/lint/hyper_log_log.rb +0 -60
  95. data/test/lint/lists.rb +0 -143
  96. data/test/lint/sets.rb +0 -140
  97. data/test/lint/sorted_sets.rb +0 -316
  98. data/test/lint/strings.rb +0 -260
  99. data/test/lint/value_types.rb +0 -122
  100. data/test/persistence_control_commands_test.rb +0 -26
  101. data/test/pipelining_commands_test.rb +0 -242
  102. data/test/publish_subscribe_test.rb +0 -282
  103. data/test/remote_server_control_commands_test.rb +0 -118
  104. data/test/scanning_test.rb +0 -413
  105. data/test/scripting_test.rb +0 -78
  106. data/test/sentinel_command_test.rb +0 -80
  107. data/test/sentinel_test.rb +0 -255
  108. data/test/sorting_test.rb +0 -59
  109. data/test/ssl_test.rb +0 -73
  110. data/test/support/connection/hiredis.rb +0 -1
  111. data/test/support/connection/ruby.rb +0 -1
  112. data/test/support/connection/synchrony.rb +0 -17
  113. data/test/support/redis_mock.rb +0 -130
  114. data/test/support/ssl/gen_certs.sh +0 -31
  115. data/test/support/ssl/trusted-ca.crt +0 -25
  116. data/test/support/ssl/trusted-ca.key +0 -27
  117. data/test/support/ssl/trusted-cert.crt +0 -81
  118. data/test/support/ssl/trusted-cert.key +0 -28
  119. data/test/support/ssl/untrusted-ca.crt +0 -26
  120. data/test/support/ssl/untrusted-ca.key +0 -27
  121. data/test/support/ssl/untrusted-cert.crt +0 -82
  122. data/test/support/ssl/untrusted-cert.key +0 -28
  123. data/test/support/wire/synchrony.rb +0 -24
  124. data/test/support/wire/thread.rb +0 -5
  125. data/test/synchrony_driver.rb +0 -88
  126. data/test/test.conf.erb +0 -9
  127. data/test/thread_safety_test.rb +0 -62
  128. data/test/transactions_test.rb +0 -264
  129. data/test/unknown_commands_test.rb +0 -14
  130. data/test/url_param_test.rb +0 -138
@@ -1,118 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- class TestRemoteServerControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_info
10
- keys = [
11
- "redis_version",
12
- "uptime_in_seconds",
13
- "uptime_in_days",
14
- "connected_clients",
15
- "used_memory",
16
- "total_connections_received",
17
- "total_commands_processed",
18
- ]
19
-
20
- info = r.info
21
-
22
- keys.each do |k|
23
- msg = "expected #info to include #{k}"
24
- assert info.keys.include?(k), msg
25
- end
26
- end
27
-
28
- def test_info_commandstats
29
- target_version "2.5.7" do
30
- r.config(:resetstat)
31
- r.ping
32
-
33
- result = r.info(:commandstats)
34
- assert_equal "1", result["ping"]["calls"]
35
- end
36
- end
37
-
38
- def test_monitor_redis_lt_2_5_0
39
- return unless version < "2.5.0"
40
-
41
- log = []
42
-
43
- wire = Wire.new do
44
- Redis.new(OPTIONS).monitor do |line|
45
- log << line
46
- break if log.size == 3
47
- end
48
- end
49
-
50
- Wire.pass while log.empty? # Faster than sleep
51
-
52
- r.set "foo", "s1"
53
-
54
- wire.join
55
-
56
- assert log[-1][%q{(db 15) "set" "foo" "s1"}]
57
- end
58
-
59
- def test_monitor_redis_gte_2_5_0
60
- return unless version >= "2.5.0"
61
-
62
- log = []
63
-
64
- wire = Wire.new do
65
- Redis.new(OPTIONS).monitor do |line|
66
- log << line
67
- break if line =~ /set/
68
- end
69
- end
70
-
71
- Wire.pass while log.empty? # Faster than sleep
72
-
73
- r.set "foo", "s1"
74
-
75
- wire.join
76
-
77
- assert log[-1] =~ /\b15\b.* "set" "foo" "s1"/
78
- end
79
-
80
- def test_monitor_returns_value_for_break
81
- result = r.monitor do |line|
82
- break line
83
- end
84
-
85
- assert_equal "OK", result
86
- end
87
-
88
- def test_echo
89
- assert_equal "foo bar baz\n", r.echo("foo bar baz\n")
90
- end
91
-
92
- def test_debug
93
- r.set "foo", "s1"
94
-
95
- assert r.debug(:object, "foo").kind_of?(String)
96
- end
97
-
98
- def test_object
99
- r.lpush "list", "value"
100
-
101
- assert_equal 1, r.object(:refcount, "list")
102
- encoding = r.object(:encoding, "list")
103
- assert "ziplist" == encoding || "quicklist" == encoding, "Wrong encoding for list"
104
- assert r.object(:idletime, "list").kind_of?(Integer)
105
- end
106
-
107
- def test_sync
108
- redis_mock(:sync => lambda { "+OK" }) do |redis|
109
- assert_equal "OK", redis.sync
110
- end
111
- end
112
-
113
- def test_slowlog
114
- r.slowlog(:reset)
115
- result = r.slowlog(:len)
116
- assert_equal 0, result
117
- end
118
- end
@@ -1,413 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
-
5
- unless defined?(Enumerator)
6
- Enumerator = Enumerable::Enumerator
7
- end
8
-
9
- class TestScanning < Test::Unit::TestCase
10
-
11
- include Helper::Client
12
-
13
- def test_scan_basic
14
- target_version "2.7.105" do
15
- r.debug :populate, 1000
16
-
17
- cursor = 0
18
- all_keys = []
19
- loop {
20
- cursor, keys = r.scan cursor
21
- all_keys += keys
22
- break if cursor == "0"
23
- }
24
-
25
- assert_equal 1000, all_keys.uniq.size
26
- end
27
- end
28
-
29
- def test_scan_count
30
- target_version "2.7.105" do
31
- r.debug :populate, 1000
32
-
33
- cursor = 0
34
- all_keys = []
35
- loop {
36
- cursor, keys = r.scan cursor, :count => 5
37
- all_keys += keys
38
- break if cursor == "0"
39
- }
40
-
41
- assert_equal 1000, all_keys.uniq.size
42
- end
43
- end
44
-
45
- def test_scan_match
46
- target_version "2.7.105" do
47
- r.debug :populate, 1000
48
-
49
- cursor = 0
50
- all_keys = []
51
- loop {
52
- cursor, keys = r.scan cursor, :match => "key:1??"
53
- all_keys += keys
54
- break if cursor == "0"
55
- }
56
-
57
- assert_equal 100, all_keys.uniq.size
58
- end
59
- end
60
-
61
- def test_scan_each_enumerator
62
- target_version "2.7.105" do
63
-
64
- r.debug :populate, 1000
65
-
66
- scan_enumerator = r.scan_each
67
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
68
-
69
- keys_from_scan = scan_enumerator.to_a.uniq
70
- all_keys = r.keys "*"
71
-
72
- assert all_keys.sort == keys_from_scan.sort
73
- end
74
- end
75
-
76
- def test_scan_each_enumerator_match
77
- target_version "2.7.105" do
78
-
79
- r.debug :populate, 1000
80
-
81
- keys_from_scan = r.scan_each(:match => "key:1??").to_a.uniq
82
- all_keys = r.keys "key:1??"
83
-
84
- assert all_keys.sort == keys_from_scan.sort
85
- end
86
- end
87
-
88
- def test_scan_each_block
89
- target_version "2.7.105" do
90
-
91
- r.debug :populate, 100
92
-
93
- keys_from_scan = []
94
- r.scan_each {|key|
95
- keys_from_scan << key
96
- }
97
-
98
- all_keys = r.keys "*"
99
-
100
- assert all_keys.sort == keys_from_scan.uniq.sort
101
- end
102
- end
103
-
104
- def test_scan_each_block_match
105
- target_version "2.7.105" do
106
-
107
- r.debug :populate, 100
108
-
109
- keys_from_scan = []
110
- r.scan_each(:match => "key:1?") {|key|
111
- keys_from_scan << key
112
- }
113
-
114
- all_keys = r.keys "key:1?"
115
-
116
- assert all_keys.sort == keys_from_scan.uniq.sort
117
- end
118
- end
119
-
120
- def test_sscan_with_encoding
121
- target_version "2.7.105" do
122
- [:intset, :hashtable].each do |enc|
123
- r.del "set"
124
-
125
- prefix = ""
126
- prefix = "ele:" if enc == :hashtable
127
-
128
- elements = []
129
- 100.times { |j| elements << "#{prefix}#{j}" }
130
-
131
- r.sadd "set", elements
132
-
133
- assert_equal enc.to_s, r.object("encoding", "set")
134
-
135
- cursor = 0
136
- all_keys = []
137
- loop {
138
- cursor, keys = r.sscan "set", cursor
139
- all_keys += keys
140
- break if cursor == "0"
141
- }
142
-
143
- assert_equal 100, all_keys.uniq.size
144
- end
145
- end
146
- end
147
-
148
- def test_sscan_each_enumerator
149
- target_version "2.7.105" do
150
- elements = []
151
- 100.times { |j| elements << "ele:#{j}" }
152
- r.sadd "set", elements
153
-
154
- scan_enumerator = r.sscan_each("set")
155
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
156
-
157
- keys_from_scan = scan_enumerator.to_a.uniq
158
- all_keys = r.smembers("set")
159
-
160
- assert all_keys.sort == keys_from_scan.sort
161
- end
162
- end
163
-
164
- def test_sscan_each_enumerator_match
165
- target_version "2.7.105" do
166
- elements = []
167
- 100.times { |j| elements << "ele:#{j}" }
168
- r.sadd "set", elements
169
-
170
- keys_from_scan = r.sscan_each("set", :match => "ele:1?").to_a.uniq
171
-
172
- all_keys = r.smembers("set").grep(/^ele:1.$/)
173
-
174
- assert all_keys.sort == keys_from_scan.sort
175
- end
176
- end
177
-
178
- def test_sscan_each_enumerator_block
179
- target_version "2.7.105" do
180
- elements = []
181
- 100.times { |j| elements << "ele:#{j}" }
182
- r.sadd "set", elements
183
-
184
- keys_from_scan = []
185
- r.sscan_each("set") do |key|
186
- keys_from_scan << key
187
- end
188
-
189
- all_keys = r.smembers("set")
190
-
191
- assert all_keys.sort == keys_from_scan.uniq.sort
192
- end
193
- end
194
-
195
- def test_sscan_each_enumerator_block_match
196
- target_version "2.7.105" do
197
- elements = []
198
- 100.times { |j| elements << "ele:#{j}" }
199
- r.sadd "set", elements
200
-
201
- keys_from_scan = []
202
- r.sscan_each("set", :match => "ele:1?") do |key|
203
- keys_from_scan << key
204
- end
205
-
206
- all_keys = r.smembers("set").grep(/^ele:1.$/)
207
-
208
- assert all_keys.sort == keys_from_scan.uniq.sort
209
- end
210
- end
211
-
212
- def test_hscan_with_encoding
213
- target_version "2.7.105" do
214
- [:ziplist, :hashtable].each do |enc|
215
- r.del "set"
216
-
217
- count = 1000
218
- count = 30 if enc == :ziplist
219
-
220
- elements = []
221
- count.times { |j| elements << "key:#{j}" << j.to_s }
222
-
223
- r.hmset "hash", *elements
224
-
225
- assert_equal enc.to_s, r.object("encoding", "hash")
226
-
227
- cursor = 0
228
- all_key_values = []
229
- loop {
230
- cursor, key_values = r.hscan "hash", cursor
231
- all_key_values.concat key_values
232
- break if cursor == "0"
233
- }
234
-
235
- keys2 = []
236
- all_key_values.each do |k, v|
237
- assert_equal "key:#{v}", k
238
- keys2 << k
239
- end
240
-
241
- assert_equal count, keys2.uniq.size
242
- end
243
- end
244
- end
245
-
246
- def test_hscan_each_enumerator
247
- target_version "2.7.105" do
248
- count = 1000
249
- elements = []
250
- count.times { |j| elements << "key:#{j}" << j.to_s }
251
- r.hmset "hash", *elements
252
-
253
- scan_enumerator = r.hscan_each("hash")
254
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
255
-
256
- keys_from_scan = scan_enumerator.to_a.uniq
257
- all_keys = r.hgetall("hash").to_a
258
-
259
- assert all_keys.sort == keys_from_scan.sort
260
- end
261
- end
262
-
263
- def test_hscan_each_enumerator_match
264
- target_version "2.7.105" do
265
- count = 100
266
- elements = []
267
- count.times { |j| elements << "key:#{j}" << j.to_s }
268
- r.hmset "hash", *elements
269
-
270
- keys_from_scan = r.hscan_each("hash", :match => "key:1?").to_a.uniq
271
- all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/}
272
-
273
- assert all_keys.sort == keys_from_scan.sort
274
- end
275
- end
276
-
277
- def test_hscan_each_block
278
- target_version "2.7.105" do
279
- count = 1000
280
- elements = []
281
- count.times { |j| elements << "key:#{j}" << j.to_s }
282
- r.hmset "hash", *elements
283
-
284
- keys_from_scan = []
285
- r.hscan_each("hash") do |field, value|
286
- keys_from_scan << [field, value]
287
- end
288
- all_keys = r.hgetall("hash").to_a
289
-
290
- assert all_keys.sort == keys_from_scan.uniq.sort
291
- end
292
- end
293
-
294
- def test_hscan_each_block_match
295
- target_version "2.7.105" do
296
- count = 1000
297
- elements = []
298
- count.times { |j| elements << "key:#{j}" << j.to_s }
299
- r.hmset "hash", *elements
300
-
301
- keys_from_scan = []
302
- r.hscan_each("hash", :match => "key:1?") do |field, value|
303
- keys_from_scan << [field, value]
304
- end
305
- all_keys = r.hgetall("hash").to_a.select{|k,v| k =~ /^key:1.$/}
306
-
307
- assert all_keys.sort == keys_from_scan.uniq.sort
308
- end
309
- end
310
-
311
- def test_zscan_with_encoding
312
- target_version "2.7.105" do
313
- [:ziplist, :skiplist].each do |enc|
314
- r.del "zset"
315
-
316
- count = 1000
317
- count = 30 if enc == :ziplist
318
-
319
- elements = []
320
- count.times { |j| elements << j << "key:#{j}" }
321
-
322
- r.zadd "zset", elements
323
-
324
- assert_equal enc.to_s, r.object("encoding", "zset")
325
-
326
- cursor = 0
327
- all_key_scores = []
328
- loop {
329
- cursor, key_scores = r.zscan "zset", cursor
330
- all_key_scores.concat key_scores
331
- break if cursor == "0"
332
- }
333
-
334
- keys2 = []
335
- all_key_scores.each do |k, v|
336
- assert_equal true, v.is_a?(Float)
337
- assert_equal "key:#{Integer(v)}", k
338
- keys2 << k
339
- end
340
-
341
- assert_equal count, keys2.uniq.size
342
- end
343
- end
344
- end
345
-
346
- def test_zscan_each_enumerator
347
- target_version "2.7.105" do
348
- count = 1000
349
- elements = []
350
- count.times { |j| elements << j << "key:#{j}" }
351
- r.zadd "zset", elements
352
-
353
- scan_enumerator = r.zscan_each "zset"
354
- assert_equal true, scan_enumerator.is_a?(::Enumerator)
355
-
356
- scores_from_scan = scan_enumerator.to_a.uniq
357
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
358
-
359
- assert member_scores.sort == scores_from_scan.sort
360
- end
361
- end
362
-
363
- def test_zscan_each_enumerator_match
364
- target_version "2.7.105" do
365
- count = 1000
366
- elements = []
367
- count.times { |j| elements << j << "key:#{j}" }
368
- r.zadd "zset", elements
369
-
370
- scores_from_scan = r.zscan_each("zset", :match => "key:1??").to_a.uniq
371
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
372
- filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/}
373
-
374
- assert filtered_members.sort == scores_from_scan.sort
375
- end
376
- end
377
-
378
- def test_zscan_each_block
379
- target_version "2.7.105" do
380
- count = 1000
381
- elements = []
382
- count.times { |j| elements << j << "key:#{j}" }
383
- r.zadd "zset", elements
384
-
385
- scores_from_scan = []
386
- r.zscan_each("zset") do |member, score|
387
- scores_from_scan << [member, score]
388
- end
389
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
390
-
391
- assert member_scores.sort == scores_from_scan.sort
392
- end
393
- end
394
-
395
- def test_zscan_each_block_match
396
- target_version "2.7.105" do
397
- count = 1000
398
- elements = []
399
- count.times { |j| elements << j << "key:#{j}" }
400
- r.zadd "zset", elements
401
-
402
- scores_from_scan = []
403
- r.zscan_each("zset", :match => "key:1??") do |member, score|
404
- scores_from_scan << [member, score]
405
- end
406
- member_scores = r.zrange("zset", 0, -1, :with_scores => true)
407
- filtered_members = member_scores.select{|k,s| k =~ /^key:1..$/}
408
-
409
- assert filtered_members.sort == scores_from_scan.sort
410
- end
411
- end
412
-
413
- end