redis 3.3.5 → 4.7.0

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