redis 4.0.1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +46 -1
  4. data/lib/redis/client.rb +29 -12
  5. data/lib/redis/cluster/command.rb +81 -0
  6. data/lib/redis/cluster/command_loader.rb +34 -0
  7. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  8. data/lib/redis/cluster/node.rb +104 -0
  9. data/lib/redis/cluster/node_key.rb +35 -0
  10. data/lib/redis/cluster/node_loader.rb +37 -0
  11. data/lib/redis/cluster/option.rb +77 -0
  12. data/lib/redis/cluster/slot.rb +69 -0
  13. data/lib/redis/cluster/slot_loader.rb +49 -0
  14. data/lib/redis/cluster.rb +286 -0
  15. data/lib/redis/connection/ruby.rb +5 -2
  16. data/lib/redis/distributed.rb +13 -6
  17. data/lib/redis/errors.rb +46 -0
  18. data/lib/redis/pipeline.rb +9 -1
  19. data/lib/redis/version.rb +1 -1
  20. data/lib/redis.rb +692 -25
  21. metadata +27 -184
  22. data/.gitignore +0 -16
  23. data/.travis/Gemfile +0 -13
  24. data/.travis.yml +0 -73
  25. data/.yardopts +0 -3
  26. data/Gemfile +0 -3
  27. data/benchmarking/logging.rb +0 -71
  28. data/benchmarking/pipeline.rb +0 -51
  29. data/benchmarking/speed.rb +0 -21
  30. data/benchmarking/suite.rb +0 -24
  31. data/benchmarking/worker.rb +0 -71
  32. data/bors.toml +0 -14
  33. data/examples/basic.rb +0 -15
  34. data/examples/consistency.rb +0 -114
  35. data/examples/dist_redis.rb +0 -43
  36. data/examples/incr-decr.rb +0 -17
  37. data/examples/list.rb +0 -26
  38. data/examples/pubsub.rb +0 -37
  39. data/examples/sentinel/sentinel.conf +0 -9
  40. data/examples/sentinel/start +0 -49
  41. data/examples/sentinel.rb +0 -41
  42. data/examples/sets.rb +0 -36
  43. data/examples/unicorn/config.ru +0 -3
  44. data/examples/unicorn/unicorn.rb +0 -20
  45. data/makefile +0 -42
  46. data/redis.gemspec +0 -42
  47. data/test/bitpos_test.rb +0 -63
  48. data/test/blocking_commands_test.rb +0 -40
  49. data/test/client_test.rb +0 -59
  50. data/test/command_map_test.rb +0 -28
  51. data/test/commands_on_hashes_test.rb +0 -19
  52. data/test/commands_on_hyper_log_log_test.rb +0 -19
  53. data/test/commands_on_lists_test.rb +0 -18
  54. data/test/commands_on_sets_test.rb +0 -75
  55. data/test/commands_on_sorted_sets_test.rb +0 -150
  56. data/test/commands_on_strings_test.rb +0 -99
  57. data/test/commands_on_value_types_test.rb +0 -171
  58. data/test/connection_handling_test.rb +0 -275
  59. data/test/connection_test.rb +0 -57
  60. data/test/db/.gitkeep +0 -0
  61. data/test/distributed_blocking_commands_test.rb +0 -44
  62. data/test/distributed_commands_on_hashes_test.rb +0 -8
  63. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -31
  64. data/test/distributed_commands_on_lists_test.rb +0 -20
  65. data/test/distributed_commands_on_sets_test.rb +0 -106
  66. data/test/distributed_commands_on_sorted_sets_test.rb +0 -16
  67. data/test/distributed_commands_on_strings_test.rb +0 -69
  68. data/test/distributed_commands_on_value_types_test.rb +0 -93
  69. data/test/distributed_commands_requiring_clustering_test.rb +0 -162
  70. data/test/distributed_connection_handling_test.rb +0 -21
  71. data/test/distributed_internals_test.rb +0 -68
  72. data/test/distributed_key_tags_test.rb +0 -50
  73. data/test/distributed_persistence_control_commands_test.rb +0 -24
  74. data/test/distributed_publish_subscribe_test.rb +0 -90
  75. data/test/distributed_remote_server_control_commands_test.rb +0 -64
  76. data/test/distributed_scripting_test.rb +0 -100
  77. data/test/distributed_sorting_test.rb +0 -18
  78. data/test/distributed_test.rb +0 -56
  79. data/test/distributed_transactions_test.rb +0 -30
  80. data/test/encoding_test.rb +0 -14
  81. data/test/error_replies_test.rb +0 -57
  82. data/test/fork_safety_test.rb +0 -60
  83. data/test/helper.rb +0 -201
  84. data/test/helper_test.rb +0 -22
  85. data/test/internals_test.rb +0 -389
  86. data/test/lint/blocking_commands.rb +0 -150
  87. data/test/lint/hashes.rb +0 -162
  88. data/test/lint/hyper_log_log.rb +0 -60
  89. data/test/lint/lists.rb +0 -143
  90. data/test/lint/sets.rb +0 -140
  91. data/test/lint/sorted_sets.rb +0 -316
  92. data/test/lint/strings.rb +0 -246
  93. data/test/lint/value_types.rb +0 -130
  94. data/test/persistence_control_commands_test.rb +0 -24
  95. data/test/pipelining_commands_test.rb +0 -238
  96. data/test/publish_subscribe_test.rb +0 -280
  97. data/test/remote_server_control_commands_test.rb +0 -175
  98. data/test/scanning_test.rb +0 -407
  99. data/test/scripting_test.rb +0 -76
  100. data/test/sentinel_command_test.rb +0 -78
  101. data/test/sentinel_test.rb +0 -253
  102. data/test/sorting_test.rb +0 -57
  103. data/test/ssl_test.rb +0 -69
  104. data/test/support/connection/hiredis.rb +0 -1
  105. data/test/support/connection/ruby.rb +0 -1
  106. data/test/support/connection/synchrony.rb +0 -17
  107. data/test/support/redis_mock.rb +0 -130
  108. data/test/support/ssl/gen_certs.sh +0 -31
  109. data/test/support/ssl/trusted-ca.crt +0 -25
  110. data/test/support/ssl/trusted-ca.key +0 -27
  111. data/test/support/ssl/trusted-cert.crt +0 -81
  112. data/test/support/ssl/trusted-cert.key +0 -28
  113. data/test/support/ssl/untrusted-ca.crt +0 -26
  114. data/test/support/ssl/untrusted-ca.key +0 -27
  115. data/test/support/ssl/untrusted-cert.crt +0 -82
  116. data/test/support/ssl/untrusted-cert.key +0 -28
  117. data/test/support/wire/synchrony.rb +0 -24
  118. data/test/support/wire/thread.rb +0 -5
  119. data/test/synchrony_driver.rb +0 -85
  120. data/test/test.conf.erb +0 -9
  121. data/test/thread_safety_test.rb +0 -60
  122. data/test/transactions_test.rb +0 -262
  123. data/test/unknown_commands_test.rb +0 -12
  124. data/test/url_param_test.rb +0 -136
@@ -1,56 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestDistributed < Test::Unit::TestCase
4
-
5
- include Helper::Distributed
6
-
7
- def test_handle_multiple_servers
8
- @r = Redis::Distributed.new ["redis://127.0.0.1:#{PORT}/15", *NODES]
9
-
10
- 100.times do |idx|
11
- @r.set(idx.to_s, "foo#{idx}")
12
- end
13
-
14
- 100.times do |idx|
15
- assert_equal "foo#{idx}", @r.get(idx.to_s)
16
- end
17
-
18
- assert_equal "0", @r.keys("*").sort.first
19
- assert_equal "string", @r.type("1")
20
- end
21
-
22
- def test_add_nodes
23
- logger = Logger.new("/dev/null")
24
-
25
- @r = Redis::Distributed.new NODES, :logger => logger, :timeout => 10
26
-
27
- assert_equal "127.0.0.1", @r.nodes[0]._client.host
28
- assert_equal PORT, @r.nodes[0]._client.port
29
- assert_equal 15, @r.nodes[0]._client.db
30
- assert_equal 10, @r.nodes[0]._client.timeout
31
- assert_equal logger, @r.nodes[0]._client.logger
32
-
33
- @r.add_node("redis://127.0.0.1:6380/14")
34
-
35
- assert_equal "127.0.0.1", @r.nodes[1]._client.host
36
- assert_equal 6380, @r.nodes[1]._client.port
37
- assert_equal 14, @r.nodes[1]._client.db
38
- assert_equal 10, @r.nodes[1]._client.timeout
39
- assert_equal logger, @r.nodes[1]._client.logger
40
- end
41
-
42
- def test_pipelining_commands_cannot_be_distributed
43
- assert_raise Redis::Distributed::CannotDistribute do
44
- r.pipelined do
45
- r.lpush "foo", "s1"
46
- r.lpush "foo", "s2"
47
- end
48
- end
49
- end
50
-
51
- def test_unknown_commands_does_not_work_by_default
52
- assert_raise NoMethodError do
53
- r.not_yet_implemented_command
54
- end
55
- end
56
- end
@@ -1,30 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestDistributedTransactions < Test::Unit::TestCase
4
-
5
- include Helper::Distributed
6
-
7
- def test_multi_discard
8
- @foo = nil
9
-
10
- assert_raise Redis::Distributed::CannotDistribute do
11
- r.multi { @foo = 1 }
12
- end
13
-
14
- assert_equal nil, @foo
15
-
16
- assert_raise Redis::Distributed::CannotDistribute do
17
- r.discard
18
- end
19
- end
20
-
21
- def test_watch_unwatch
22
- assert_raise Redis::Distributed::CannotDistribute do
23
- r.watch("foo")
24
- end
25
-
26
- assert_raise Redis::Distributed::CannotDistribute do
27
- r.unwatch
28
- end
29
- end
30
- end
@@ -1,14 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestEncoding < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- def test_returns_properly_encoded_strings
8
- with_external_encoding("UTF-8") do
9
- r.set "foo", "שלום"
10
-
11
- assert_equal "Shalom שלום", "Shalom " + r.get("foo")
12
- end
13
- end
14
- end
@@ -1,57 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestErrorReplies < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- # Every test shouldn't disconnect from the server. Also, when error replies are
8
- # in play, the protocol should never get into an invalid state where there are
9
- # pending replies in the connection. Calling INFO after every test ensures that
10
- # the protocol is still in a valid state.
11
- def with_reconnection_check
12
- before = r.info["total_connections_received"]
13
- yield(r)
14
- after = r.info["total_connections_received"]
15
- ensure
16
- assert_equal before, after
17
- end
18
-
19
- def test_error_reply_for_single_command
20
- with_reconnection_check do
21
- begin
22
- r.unknown_command
23
- rescue => ex
24
- ensure
25
- assert ex.message =~ /unknown command/i
26
- end
27
- end
28
- end
29
-
30
- def test_raise_first_error_reply_in_pipeline
31
- with_reconnection_check do
32
- begin
33
- r.pipelined do
34
- r.set("foo", "s1")
35
- r.incr("foo") # not an integer
36
- r.lpush("foo", "value") # wrong kind of value
37
- end
38
- rescue => ex
39
- ensure
40
- assert ex.message =~ /not an integer/i
41
- end
42
- end
43
- end
44
-
45
- def test_recover_from_raise_in__call_loop
46
- with_reconnection_check do
47
- begin
48
- r._client.call_loop([:invalid_monitor]) do
49
- assert false # Should never be executed
50
- end
51
- rescue => ex
52
- ensure
53
- assert ex.message =~ /unknown command/i
54
- end
55
- end
56
- end
57
- end
@@ -1,60 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestForkSafety < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- driver(:ruby, :hiredis) do
8
- def test_fork_safety
9
- redis = Redis.new(OPTIONS)
10
- redis.set "foo", 1
11
-
12
- child_pid = fork do
13
- begin
14
- # InheritedError triggers a reconnect,
15
- # so we need to disable reconnects to force
16
- # the exception bubble up
17
- redis.without_reconnect do
18
- redis.set "foo", 2
19
- end
20
- rescue Redis::InheritedError
21
- exit 127
22
- end
23
- end
24
-
25
- _, status = Process.wait2(child_pid)
26
-
27
- assert_equal 127, status.exitstatus
28
- assert_equal "1", redis.get("foo")
29
-
30
- rescue NotImplementedError => error
31
- raise unless error.message =~ /fork is not available/
32
- end
33
-
34
- def test_fork_safety_with_enabled_inherited_socket
35
- redis = Redis.new(OPTIONS.merge(:inherit_socket => true))
36
- redis.set "foo", 1
37
-
38
- child_pid = fork do
39
- begin
40
- # InheritedError triggers a reconnect,
41
- # so we need to disable reconnects to force
42
- # the exception bubble up
43
- redis.without_reconnect do
44
- redis.set "foo", 2
45
- end
46
- rescue Redis::InheritedError
47
- exit 127
48
- end
49
- end
50
-
51
- _, status = Process.wait2(child_pid)
52
-
53
- assert_equal 0, status.exitstatus
54
- assert_equal "2", redis.get("foo")
55
-
56
- rescue NotImplementedError => error
57
- raise unless error.message =~ /fork is not available/
58
- end
59
- end
60
- end
data/test/helper.rb DELETED
@@ -1,201 +0,0 @@
1
- require "test/unit"
2
- require "logger"
3
- require "stringio"
4
-
5
- $VERBOSE = true
6
-
7
- ENV["DRIVER"] ||= "ruby"
8
-
9
- require_relative "../lib/redis"
10
- require_relative "../lib/redis/distributed"
11
- require_relative "../lib/redis/connection/#{ENV["DRIVER"]}"
12
-
13
- require_relative "support/redis_mock"
14
- require_relative "support/connection/#{ENV["DRIVER"]}"
15
-
16
- PORT = 6381
17
- OPTIONS = {:port => PORT, :db => 15, :timeout => Float(ENV["TIMEOUT"] || 0.1)}
18
- NODES = ["redis://127.0.0.1:#{PORT}/15"]
19
-
20
- def init(redis)
21
- begin
22
- redis.select 14
23
- redis.flushdb
24
- redis.select 15
25
- redis.flushdb
26
- redis
27
- rescue Redis::CannotConnectError
28
- puts <<-EOS
29
-
30
- Cannot connect to Redis.
31
-
32
- Make sure Redis is running on localhost, port #{PORT}.
33
- This testing suite connects to the database 15.
34
-
35
- Try this once:
36
-
37
- $ make clean
38
-
39
- Then run the build again:
40
-
41
- $ make
42
-
43
- EOS
44
- exit 1
45
- end
46
- end
47
-
48
- def driver(*drivers, &blk)
49
- if drivers.map(&:to_s).include?(ENV["DRIVER"])
50
- class_eval(&blk)
51
- end
52
- end
53
-
54
- module Helper
55
-
56
- def run(runner)
57
- if respond_to?(:around)
58
- around { super(runner) }
59
- else
60
- super
61
- end
62
- end
63
-
64
- def silent
65
- verbose, $VERBOSE = $VERBOSE, false
66
-
67
- begin
68
- yield
69
- ensure
70
- $VERBOSE = verbose
71
- end
72
- end
73
-
74
- def with_external_encoding(encoding)
75
- original_encoding = Encoding.default_external
76
-
77
- begin
78
- silent { Encoding.default_external = Encoding.find(encoding) }
79
- yield
80
- ensure
81
- silent { Encoding.default_external = original_encoding }
82
- end
83
- end
84
-
85
- class Version
86
-
87
- include Comparable
88
-
89
- attr :parts
90
-
91
- def initialize(v)
92
- case v
93
- when Version
94
- @parts = v.parts
95
- else
96
- @parts = v.to_s.split(".")
97
- end
98
- end
99
-
100
- def <=>(other)
101
- other = Version.new(other)
102
- length = [self.parts.length, other.parts.length].max
103
- length.times do |i|
104
- a, b = self.parts[i], other.parts[i]
105
-
106
- return -1 if a.nil?
107
- return +1 if b.nil?
108
- return a.to_i <=> b.to_i if a != b
109
- end
110
-
111
- 0
112
- end
113
- end
114
-
115
- module Generic
116
-
117
- include Helper
118
-
119
- attr_reader :log
120
- attr_reader :redis
121
-
122
- alias :r :redis
123
-
124
- def setup
125
- @log = StringIO.new
126
- @redis = init _new_client
127
-
128
- # Run GC to make sure orphaned connections are closed.
129
- GC.start
130
- end
131
-
132
- def teardown
133
- @redis.quit if @redis
134
- end
135
-
136
- def redis_mock(commands, options = {}, &blk)
137
- RedisMock.start(commands, options) do |port|
138
- yield _new_client(options.merge(:port => port))
139
- end
140
- end
141
-
142
- def redis_mock_with_handler(handler, options = {}, &blk)
143
- RedisMock.start_with_handler(handler, options) do |port|
144
- yield _new_client(options.merge(:port => port))
145
- end
146
- end
147
-
148
- def assert_in_range(range, value)
149
- assert range.include?(value), "expected #{value} to be in #{range.inspect}"
150
- end
151
-
152
- def target_version(target)
153
- if version < target
154
- skip("Requires Redis > #{target}") if respond_to?(:skip)
155
- else
156
- yield
157
- end
158
- end
159
- end
160
-
161
- module Client
162
-
163
- include Generic
164
-
165
- def version
166
- Version.new(redis.info["redis_version"])
167
- end
168
-
169
- private
170
-
171
- def _format_options(options)
172
- OPTIONS.merge(:logger => ::Logger.new(@log)).merge(options)
173
- end
174
-
175
- def _new_client(options = {})
176
- Redis.new(_format_options(options).merge(:driver => ENV["DRIVER"]))
177
- end
178
- end
179
-
180
- module Distributed
181
-
182
- include Generic
183
-
184
- def version
185
- Version.new(redis.info.first["redis_version"])
186
- end
187
-
188
- private
189
-
190
- def _format_options(options)
191
- {
192
- :timeout => OPTIONS[:timeout],
193
- :logger => ::Logger.new(@log),
194
- }.merge(options)
195
- end
196
-
197
- def _new_client(options = {})
198
- Redis::Distributed.new(NODES, _format_options(options).merge(:driver => ENV["conn"]))
199
- end
200
- end
201
- end
data/test/helper_test.rb DELETED
@@ -1,22 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestHelper < Test::Unit::TestCase
4
-
5
- include Helper
6
-
7
- def test_version_comparison
8
- v = Version.new("2.0.1")
9
-
10
- assert v > "1"
11
- assert v > "2"
12
- assert v < "3"
13
- assert v < "10"
14
-
15
- assert v < "2.1"
16
- assert v < "2.0.2"
17
- assert v < "2.0.1.1"
18
- assert v < "2.0.10"
19
-
20
- assert v == "2.0.1"
21
- end
22
- end