redis 3.0.0 → 4.2.2

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.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +269 -0
  3. data/README.md +295 -58
  4. data/lib/redis.rb +1760 -451
  5. data/lib/redis/client.rb +355 -88
  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 +90 -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 +12 -8
  19. data/lib/redis/connection/registry.rb +2 -1
  20. data/lib/redis/connection/ruby.rb +232 -63
  21. data/lib/redis/connection/synchrony.rb +41 -14
  22. data/lib/redis/distributed.rb +205 -70
  23. data/lib/redis/errors.rb +48 -0
  24. data/lib/redis/hash_ring.rb +31 -73
  25. data/lib/redis/pipeline.rb +74 -18
  26. data/lib/redis/subscribe.rb +24 -13
  27. data/lib/redis/version.rb +3 -1
  28. metadata +63 -160
  29. data/.gitignore +0 -10
  30. data/.order +0 -169
  31. data/.travis.yml +0 -50
  32. data/.travis/Gemfile +0 -11
  33. data/.yardopts +0 -3
  34. data/Rakefile +0 -392
  35. data/benchmarking/logging.rb +0 -62
  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/dist_redis.rb +0 -43
  42. data/examples/incr-decr.rb +0 -17
  43. data/examples/list.rb +0 -26
  44. data/examples/pubsub.rb +0 -31
  45. data/examples/sets.rb +0 -36
  46. data/examples/unicorn/config.ru +0 -3
  47. data/examples/unicorn/unicorn.rb +0 -20
  48. data/redis.gemspec +0 -41
  49. data/test/blocking_commands_test.rb +0 -42
  50. data/test/command_map_test.rb +0 -30
  51. data/test/commands_on_hashes_test.rb +0 -21
  52. data/test/commands_on_lists_test.rb +0 -20
  53. data/test/commands_on_sets_test.rb +0 -77
  54. data/test/commands_on_sorted_sets_test.rb +0 -109
  55. data/test/commands_on_strings_test.rb +0 -83
  56. data/test/commands_on_value_types_test.rb +0 -99
  57. data/test/connection_handling_test.rb +0 -189
  58. data/test/db/.gitignore +0 -1
  59. data/test/distributed_blocking_commands_test.rb +0 -46
  60. data/test/distributed_commands_on_hashes_test.rb +0 -10
  61. data/test/distributed_commands_on_lists_test.rb +0 -22
  62. data/test/distributed_commands_on_sets_test.rb +0 -83
  63. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  64. data/test/distributed_commands_on_strings_test.rb +0 -48
  65. data/test/distributed_commands_on_value_types_test.rb +0 -87
  66. data/test/distributed_commands_requiring_clustering_test.rb +0 -148
  67. data/test/distributed_connection_handling_test.rb +0 -23
  68. data/test/distributed_internals_test.rb +0 -15
  69. data/test/distributed_key_tags_test.rb +0 -52
  70. data/test/distributed_persistence_control_commands_test.rb +0 -26
  71. data/test/distributed_publish_subscribe_test.rb +0 -92
  72. data/test/distributed_remote_server_control_commands_test.rb +0 -53
  73. data/test/distributed_scripting_test.rb +0 -102
  74. data/test/distributed_sorting_test.rb +0 -20
  75. data/test/distributed_test.rb +0 -58
  76. data/test/distributed_transactions_test.rb +0 -32
  77. data/test/encoding_test.rb +0 -18
  78. data/test/error_replies_test.rb +0 -59
  79. data/test/helper.rb +0 -188
  80. data/test/helper_test.rb +0 -22
  81. data/test/internals_test.rb +0 -214
  82. data/test/lint/blocking_commands.rb +0 -124
  83. data/test/lint/hashes.rb +0 -162
  84. data/test/lint/lists.rb +0 -143
  85. data/test/lint/sets.rb +0 -96
  86. data/test/lint/sorted_sets.rb +0 -201
  87. data/test/lint/strings.rb +0 -157
  88. data/test/lint/value_types.rb +0 -106
  89. data/test/persistence_control_commands_test.rb +0 -26
  90. data/test/pipelining_commands_test.rb +0 -195
  91. data/test/publish_subscribe_test.rb +0 -153
  92. data/test/remote_server_control_commands_test.rb +0 -104
  93. data/test/scripting_test.rb +0 -78
  94. data/test/sorting_test.rb +0 -45
  95. data/test/support/connection/hiredis.rb +0 -1
  96. data/test/support/connection/ruby.rb +0 -1
  97. data/test/support/connection/synchrony.rb +0 -17
  98. data/test/support/redis_mock.rb +0 -92
  99. data/test/support/wire/synchrony.rb +0 -24
  100. data/test/support/wire/thread.rb +0 -5
  101. data/test/synchrony_driver.rb +0 -57
  102. data/test/test.conf +0 -9
  103. data/test/thread_safety_test.rb +0 -32
  104. data/test/transactions_test.rb +0 -244
  105. data/test/unknown_commands_test.rb +0 -14
  106. data/test/url_param_test.rb +0 -64
@@ -1,26 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestPersistenceControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_save
10
- redis_mock(:save => lambda { "+SAVE" }) do |redis|
11
- assert_equal "SAVE", redis.save
12
- end
13
- end
14
-
15
- def test_bgsave
16
- redis_mock(:bgsave => lambda { "+BGSAVE" }) do |redis|
17
- assert_equal "BGSAVE", redis.bgsave
18
- end
19
- end
20
-
21
- def test_lastsave
22
- redis_mock(:lastsave => lambda { "+LASTSAVE" }) do |redis|
23
- assert_equal "LASTSAVE", redis.lastsave
24
- end
25
- end
26
- end
@@ -1,195 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestPipeliningCommands < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_bulk_commands
10
- r.pipelined do
11
- r.lpush "foo", "s1"
12
- r.lpush "foo", "s2"
13
- end
14
-
15
- assert_equal 2, r.llen("foo")
16
- assert_equal "s2", r.lpop("foo")
17
- assert_equal "s1", r.lpop("foo")
18
- end
19
-
20
- def test_multi_bulk_commands
21
- r.pipelined do
22
- r.mset("foo", "s1", "bar", "s2")
23
- r.mset("baz", "s3", "qux", "s4")
24
- end
25
-
26
- assert_equal "s1", r.get("foo")
27
- assert_equal "s2", r.get("bar")
28
- assert_equal "s3", r.get("baz")
29
- assert_equal "s4", r.get("qux")
30
- end
31
-
32
- def test_bulk_and_multi_bulk_commands_mixed
33
- r.pipelined do
34
- r.lpush "foo", "s1"
35
- r.lpush "foo", "s2"
36
- r.mset("baz", "s3", "qux", "s4")
37
- end
38
-
39
- assert_equal 2, r.llen("foo")
40
- assert_equal "s2", r.lpop("foo")
41
- assert_equal "s1", r.lpop("foo")
42
- assert_equal "s3", r.get("baz")
43
- assert_equal "s4", r.get("qux")
44
- end
45
-
46
- def test_multi_bulk_and_bulk_commands_mixed
47
- r.pipelined do
48
- r.mset("baz", "s3", "qux", "s4")
49
- r.lpush "foo", "s1"
50
- r.lpush "foo", "s2"
51
- end
52
-
53
- assert_equal 2, r.llen("foo")
54
- assert_equal "s2", r.lpop("foo")
55
- assert_equal "s1", r.lpop("foo")
56
- assert_equal "s3", r.get("baz")
57
- assert_equal "s4", r.get("qux")
58
- end
59
-
60
- def test_pipelined_with_an_empty_block
61
- assert_nothing_raised do
62
- r.pipelined do
63
- end
64
- end
65
-
66
- assert_equal 0, r.dbsize
67
- end
68
-
69
- def test_returning_the_result_of_a_pipeline
70
- result = r.pipelined do
71
- r.set "foo", "bar"
72
- r.get "foo"
73
- r.get "bar"
74
- end
75
-
76
- assert_equal ["OK", "bar", nil], result
77
- end
78
-
79
- def test_assignment_of_results_inside_the_block
80
- r.pipelined do
81
- @first = r.sadd("foo", 1)
82
- @second = r.sadd("foo", 1)
83
- end
84
-
85
- assert_equal true, @first.value
86
- assert_equal false, @second.value
87
- end
88
-
89
- # Although we could support accessing the values in these futures,
90
- # it doesn't make a lot of sense.
91
- def test_assignment_of_results_inside_the_block_with_errors
92
- assert_raise(Redis::CommandError) do
93
- r.pipelined do
94
- r.doesnt_exist
95
- @first = r.sadd("foo", 1)
96
- r.doesnt_exist
97
- @second = r.sadd("foo", 1)
98
- r.doesnt_exist
99
- end
100
- end
101
-
102
- assert_raise(Redis::FutureNotReady) { @first.value }
103
- assert_raise(Redis::FutureNotReady) { @second.value }
104
- end
105
-
106
- def test_assignment_of_results_inside_a_nested_block
107
- r.pipelined do
108
- @first = r.sadd("foo", 1)
109
-
110
- r.pipelined do
111
- @second = r.sadd("foo", 1)
112
- end
113
- end
114
-
115
- assert_equal true, @first.value
116
- assert_equal false, @second.value
117
- end
118
-
119
- def test_futures_raise_when_confused_with_something_else
120
- r.pipelined do
121
- @result = r.sadd("foo", 1)
122
- end
123
-
124
- assert_raise(NoMethodError) { @result.to_s }
125
- end
126
-
127
- def test_futures_raise_when_trying_to_access_their_values_too_early
128
- r.pipelined do
129
- assert_raise(Redis::FutureNotReady) do
130
- r.sadd("foo", 1).value
131
- end
132
- end
133
- end
134
-
135
- def test_returning_the_result_of_an_empty_pipeline
136
- result = r.pipelined do
137
- end
138
-
139
- assert_equal [], result
140
- end
141
-
142
- def test_nesting_pipeline_blocks
143
- r.pipelined do
144
- r.set("foo", "s1")
145
- r.pipelined do
146
- r.set("bar", "s2")
147
- end
148
- end
149
-
150
- assert_equal "s1", r.get("foo")
151
- assert_equal "s2", r.get("bar")
152
- end
153
-
154
- def test_info_in_a_pipeline_returns_hash
155
- result = r.pipelined do
156
- r.info
157
- end
158
-
159
- assert result.first.kind_of?(Hash)
160
- end
161
-
162
- def test_config_get_in_a_pipeline_returns_hash
163
- result = r.pipelined do
164
- r.config(:get, "*")
165
- end
166
-
167
- assert result.first.kind_of?(Hash)
168
- end
169
-
170
- def test_hgetall_in_a_pipeline_returns_hash
171
- r.hmset("hash", "field", "value")
172
- result = r.pipelined do
173
- r.hgetall("hash")
174
- end
175
-
176
- assert_equal result.first, { "field" => "value" }
177
- end
178
-
179
- def test_keys_in_a_pipeline
180
- r.set("key", "value")
181
- result = r.pipelined do
182
- r.keys("*")
183
- end
184
-
185
- assert_equal ["key"], result.first
186
- end
187
-
188
- def test_pipeline_yields_a_connection
189
- r.pipelined do |p|
190
- p.set("foo", "bar")
191
- end
192
-
193
- assert_equal "bar", r.get("foo")
194
- end
195
- end
@@ -1,153 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestPublishSubscribe < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_subscribe_and_unsubscribe
10
- @subscribed = false
11
- @unsubscribed = false
12
-
13
- wire = Wire.new do
14
- r.subscribe("foo") do |on|
15
- on.subscribe do |channel, total|
16
- @subscribed = true
17
- @t1 = total
18
- end
19
-
20
- on.message do |channel, message|
21
- if message == "s1"
22
- r.unsubscribe
23
- @message = message
24
- end
25
- end
26
-
27
- on.unsubscribe do |channel, total|
28
- @unsubscribed = true
29
- @t2 = total
30
- end
31
- end
32
- end
33
-
34
- # Wait until the subscription is active before publishing
35
- Wire.pass while !@subscribed
36
-
37
- Redis.new(OPTIONS).publish("foo", "s1")
38
-
39
- wire.join
40
-
41
- assert @subscribed
42
- assert_equal 1, @t1
43
- assert @unsubscribed
44
- assert_equal 0, @t2
45
- assert_equal "s1", @message
46
- end
47
-
48
- def test_psubscribe_and_punsubscribe
49
- @subscribed = false
50
- @unsubscribed = false
51
-
52
- wire = Wire.new do
53
- r.psubscribe("f*") do |on|
54
- on.psubscribe do |pattern, total|
55
- @subscribed = true
56
- @t1 = total
57
- end
58
-
59
- on.pmessage do |pattern, channel, message|
60
- if message == "s1"
61
- r.punsubscribe
62
- @message = message
63
- end
64
- end
65
-
66
- on.punsubscribe do |pattern, total|
67
- @unsubscribed = true
68
- @t2 = total
69
- end
70
-
71
- listening = true
72
- end
73
- end
74
-
75
- # Wait until the subscription is active before publishing
76
- Wire.pass while !@subscribed
77
-
78
- Redis.new(OPTIONS).publish("foo", "s1")
79
-
80
- wire.join
81
-
82
- assert @subscribed
83
- assert_equal 1, @t1
84
- assert @unsubscribed
85
- assert_equal 0, @t2
86
- assert_equal "s1", @message
87
- end
88
-
89
- def test_subscribe_within_subscribe
90
- @channels = []
91
-
92
- wire = Wire.new do
93
- r.subscribe("foo") do |on|
94
- on.subscribe do |channel, total|
95
- @channels << channel
96
-
97
- r.subscribe("bar") if channel == "foo"
98
- r.unsubscribe if channel == "bar"
99
- end
100
- end
101
- end
102
-
103
- wire.join
104
-
105
- assert_equal ["foo", "bar"], @channels
106
- end
107
-
108
- def test_other_commands_within_a_subscribe
109
- assert_raise Redis::CommandError do
110
- r.subscribe("foo") do |on|
111
- on.subscribe do |channel, total|
112
- r.set("bar", "s2")
113
- end
114
- end
115
- end
116
- end
117
-
118
- def test_subscribe_without_a_block
119
- assert_raise LocalJumpError do
120
- r.subscribe("foo")
121
- end
122
- end
123
-
124
- def test_unsubscribe_without_a_subscribe
125
- assert_raise RuntimeError do
126
- r.unsubscribe
127
- end
128
-
129
- assert_raise RuntimeError do
130
- r.punsubscribe
131
- end
132
- end
133
-
134
- def test_subscribe_past_a_timeout
135
- # For some reason, a thread here doesn't reproduce the issue.
136
- sleep = %{sleep #{OPTIONS[:timeout] * 2}}
137
- publish = %{echo "publish foo bar\r\n" | nc localhost #{OPTIONS[:port]}}
138
- cmd = [sleep, publish].join("; ")
139
-
140
- IO.popen(cmd, "r+") do |pipe|
141
- received = false
142
-
143
- r.subscribe "foo" do |on|
144
- on.message do |channel, message|
145
- received = true
146
- r.unsubscribe
147
- end
148
- end
149
-
150
- assert received
151
- end
152
- end
153
- end
@@ -1,104 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestRemoteServerControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Client
8
-
9
- def test_info
10
- %w(last_save_time redis_version total_connections_received connected_clients total_commands_processed connected_slaves uptime_in_seconds used_memory uptime_in_days changes_since_last_save).each do |x|
11
- assert r.info.keys.include?(x)
12
- end
13
- end
14
-
15
- def test_info_commandstats
16
- return if version < "2.9.0"
17
-
18
- r.config(:resetstat)
19
- r.ping
20
-
21
- result = r.info(:commandstats)
22
- assert_equal "1", result["ping"]["calls"]
23
- end
24
-
25
- def test_monitor_redis_lt_2_5_0
26
- return unless version < "2.5.0"
27
-
28
- log = []
29
-
30
- wire = Wire.new do
31
- Redis.new(OPTIONS).monitor do |line|
32
- log << line
33
- break if log.size == 3
34
- end
35
- end
36
-
37
- Wire.pass while log.empty? # Faster than sleep
38
-
39
- r.set "foo", "s1"
40
-
41
- wire.join
42
-
43
- assert log[-1][%q{(db 15) "set" "foo" "s1"}]
44
- end
45
-
46
- def test_monitor_redis_gte_2_5_0
47
- return unless version >= "2.5.0"
48
-
49
- log = []
50
-
51
- wire = Wire.new do
52
- Redis.new(OPTIONS).monitor do |line|
53
- log << line
54
- break if line =~ /set/
55
- end
56
- end
57
-
58
- Wire.pass while log.empty? # Faster than sleep
59
-
60
- r.set "foo", "s1"
61
-
62
- wire.join
63
-
64
- assert log[-1] =~ /\b15\b.* "set" "foo" "s1"/
65
- end
66
-
67
- def test_monitor_returns_value_for_break
68
- result = r.monitor do |line|
69
- break line
70
- end
71
-
72
- assert_equal result, "OK"
73
- end
74
-
75
- def test_echo
76
- assert_equal "foo bar baz\n", r.echo("foo bar baz\n")
77
- end
78
-
79
- def test_debug
80
- r.set "foo", "s1"
81
-
82
- assert r.debug(:object, "foo").kind_of?(String)
83
- end
84
-
85
- def test_object
86
- r.lpush "list", "value"
87
-
88
- assert_equal r.object(:refcount, "list"), 1
89
- assert_equal r.object(:encoding, "list"), "ziplist"
90
- assert r.object(:idletime, "list").kind_of?(Fixnum)
91
- end
92
-
93
- def test_sync
94
- redis_mock(:sync => lambda { "+OK" }) do |redis|
95
- assert_equal "OK", redis.sync
96
- end
97
- end
98
-
99
- def test_slowlog
100
- r.slowlog(:reset)
101
- result = r.slowlog(:len)
102
- assert_equal result, 0
103
- end
104
- end