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
data/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- nohup.out
2
- redis/*
3
- rdsrv
4
- pkg/*
5
- coverage/*
6
- .idea
7
- *.rdb
8
- *.swp
9
- .yardoc
10
- doc/
data/.order DELETED
@@ -1,169 +0,0 @@
1
- {
2
- "connection": [
3
- "auth",
4
- "select",
5
- "ping",
6
- "echo",
7
- "quit"
8
- ],
9
- "server": [
10
- "bgrewriteaof",
11
- "bgsave",
12
- "config",
13
- "dbsize",
14
- "debug",
15
- "flushall",
16
- "flushdb",
17
- "info",
18
- "lastsave",
19
- "monitor",
20
- "save",
21
- "shutdown",
22
- "slaveof",
23
- "slowlog",
24
- "sync",
25
- "time"
26
- ],
27
- "generic": [
28
- "persist",
29
- "expire",
30
- "expireat",
31
- "ttl",
32
- "pexpire",
33
- "pexpireat",
34
- "pttl",
35
- "dump",
36
- "restore",
37
- "del",
38
- "exists",
39
- "keys",
40
- "migrate",
41
- "move",
42
- "object",
43
- "randomkey",
44
- "rename",
45
- "renamenx",
46
- "sort",
47
- "type"
48
- ],
49
- "string": [
50
- "decr",
51
- "decrby",
52
- "incr",
53
- "incrby",
54
- "incrbyfloat",
55
- "set",
56
- "setex",
57
- "psetex",
58
- "setnx",
59
- "mset",
60
- "mapped_mset",
61
- "msetnx",
62
- "mapped_msetnx",
63
- "get",
64
- "mget",
65
- "mapped_mget",
66
- "setrange",
67
- "getrange",
68
- "setbit",
69
- "getbit",
70
- "append",
71
- "bitcount",
72
- "getset",
73
- "strlen"
74
- ],
75
- "list": [
76
- "llen",
77
- "lpush",
78
- "lpushx",
79
- "rpush",
80
- "rpushx",
81
- "lpop",
82
- "rpop",
83
- "rpoplpush",
84
- "_bpop",
85
- "blpop",
86
- "brpop",
87
- "brpoplpush",
88
- "lindex",
89
- "linsert",
90
- "lrange",
91
- "lrem",
92
- "lset",
93
- "ltrim",
94
- "bitop"
95
- ],
96
- "set": [
97
- "scard",
98
- "sadd",
99
- "srem",
100
- "spop",
101
- "srandmember",
102
- "smove",
103
- "sismember",
104
- "smembers",
105
- "sdiff",
106
- "sdiffstore",
107
- "sinter",
108
- "sinterstore",
109
- "sunion",
110
- "sunionstore"
111
- ],
112
- "sorted_set": [
113
- "zcard",
114
- "zadd",
115
- "zincrby",
116
- "zrem",
117
- "zscore",
118
- "zrange",
119
- "zrevrange",
120
- "zrank",
121
- "zrevrank",
122
- "zremrangebyrank",
123
- "zrangebyscore",
124
- "zrevrangebyscore",
125
- "zremrangebyscore",
126
- "zcount",
127
- "zinterstore",
128
- "zunionstore"
129
- ],
130
- "hash": [
131
- "hlen",
132
- "hset",
133
- "hsetnx",
134
- "hmset",
135
- "mapped_hmset",
136
- "hget",
137
- "hmget",
138
- "mapped_hmget",
139
- "hdel",
140
- "hexists",
141
- "hincrby",
142
- "hincrbyfloat",
143
- "hkeys",
144
- "hvals",
145
- "hgetall"
146
- ],
147
- "pubsub": [
148
- "publish",
149
- "subscribed?",
150
- "subscribe",
151
- "unsubscribe",
152
- "psubscribe",
153
- "punsubscribe"
154
- ],
155
- "transactions": [
156
- "watch",
157
- "unwatch",
158
- "pipelined",
159
- "multi",
160
- "exec",
161
- "discard"
162
- ],
163
- "scripting": [
164
- "script",
165
- "_eval",
166
- "eval",
167
- "evalsha"
168
- ]
169
- }
@@ -1,50 +0,0 @@
1
- language: ruby
2
-
3
- branches:
4
- only:
5
- - master
6
- - test-unit
7
-
8
- rvm:
9
- - 1.8.7
10
- - 1.9.2
11
- - 1.9.3
12
- - jruby-18mode
13
- - jruby-19mode
14
-
15
- gemfile:
16
- - .travis/Gemfile
17
-
18
- env:
19
- - conn=ruby
20
- - conn=hiredis
21
- - conn=synchrony
22
-
23
- matrix:
24
- exclude:
25
- # hiredis
26
- - rvm: jruby-18mode
27
- gemfile: .travis/Gemfile
28
- env: conn=hiredis
29
- - rvm: jruby-19mode
30
- gemfile: .travis/Gemfile
31
- env: conn=hiredis
32
-
33
- # synchrony
34
- - rvm: 1.8.7
35
- gemfile: .travis/Gemfile
36
- env: conn=synchrony
37
- - rvm: jruby-18mode
38
- gemfile: .travis/Gemfile
39
- env: conn=synchrony
40
- - rvm: jruby-19mode
41
- gemfile: .travis/Gemfile
42
- env: conn=synchrony
43
-
44
- notifications:
45
- irc:
46
- - irc.freenode.net#redis-rb
47
- email:
48
- - damian.janowski@gmail.com
49
- - michel@soveran.com
50
- - pcnoordhuis@gmail.com
@@ -1,11 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec :path => "../"
4
-
5
- case ENV["conn"]
6
- when "hiredis"
7
- gem "hiredis"
8
- when "synchrony"
9
- gem "hiredis"
10
- gem "em-synchrony"
11
- end
data/.yardopts DELETED
@@ -1,3 +0,0 @@
1
- --exclude redis/connection
2
- --exclude redis/compat
3
- --markup markdown
data/Rakefile DELETED
@@ -1,392 +0,0 @@
1
- require 'rubygems'
2
- require 'rubygems/package_task'
3
- require 'rake/testtask'
4
-
5
- $:.unshift File.join(File.dirname(__FILE__), 'lib')
6
- require 'redis/version'
7
-
8
- REDIS_DIR = File.expand_path(File.join("..", "test"), __FILE__)
9
- REDIS_CNF = File.join(REDIS_DIR, "test.conf")
10
- REDIS_PID = File.join(REDIS_DIR, "db", "redis.pid")
11
-
12
- task :default => :run
13
-
14
- desc "Run tests and manage server start/stop"
15
- task :run => [:start, :test, :stop]
16
-
17
- desc "Start the Redis server"
18
- task :start do
19
- redis_running = \
20
- begin
21
- File.exists?(REDIS_PID) && Process.kill(0, File.read(REDIS_PID).to_i)
22
- rescue Errno::ESRCH
23
- FileUtils.rm REDIS_PID
24
- false
25
- end
26
-
27
- unless redis_running
28
- unless system("which redis-server")
29
- STDERR.puts "redis-server not in PATH"
30
- exit 1
31
- end
32
-
33
- unless system("redis-server #{REDIS_CNF}")
34
- STDERR.puts "could not start redis-server"
35
- exit 1
36
- end
37
- end
38
- end
39
-
40
- desc "Stop the Redis server"
41
- task :stop do
42
- if File.exists?(REDIS_PID)
43
- Process.kill "INT", File.read(REDIS_PID).to_i
44
- FileUtils.rm REDIS_PID
45
- end
46
- end
47
-
48
- Rake::TestTask.new do |t|
49
- t.options = "-v"
50
- t.libs << "test"
51
- t.test_files = FileList["test/*_test.rb"]
52
- end
53
-
54
- task :doc => ["doc:generate", "doc:prepare"]
55
-
56
- namespace :doc do
57
- task :generate do
58
- require "shellwords"
59
-
60
- `rm -rf doc`
61
-
62
- current_branch = `git branch`[/^\* (.*)$/, 1]
63
-
64
- begin
65
- tags = `git tag -l`.split("\n").sort.reverse
66
-
67
- tags.each do |tag|
68
- `git checkout -q #{tag} 2>/dev/null`
69
-
70
- unless $?.success?
71
- $stderr.puts "Need a clean working copy. Please git-stash away."
72
- exit 1
73
- end
74
-
75
- puts tag
76
-
77
- `mkdir -p doc/#{tag}`
78
-
79
- files = `git ls-tree -r HEAD lib`.split("\n").map do |line|
80
- line[/\t(.*)$/, 1]
81
- end
82
-
83
- opts = [
84
- "--title", "A Ruby client for Redis",
85
- "--output", "doc/#{tag}",
86
- "--no-cache",
87
- "--no-save",
88
- "-q",
89
- *files
90
- ]
91
-
92
- `yardoc #{Shellwords.shelljoin opts}`
93
- end
94
- ensure
95
- `git checkout -q #{current_branch}`
96
- end
97
- end
98
-
99
- task :prepare do
100
- versions = `git tag -l`.split("\n").grep(/^v/).sort
101
- latest_version = versions.last
102
-
103
- File.open("doc/.htaccess", "w") do |file|
104
- file.puts "RedirectMatch 302 ^/?$ /#{latest_version}"
105
- end
106
-
107
- File.open("doc/robots.txt", "w") do |file|
108
- file.puts "User-Agent: *"
109
-
110
- (versions - [latest_version]).each do |version|
111
- file.puts "Disallow: /#{version}"
112
- end
113
- end
114
-
115
- google_analytics = <<-EOS
116
- <script type="text/javascript">
117
-
118
- var _gaq = _gaq || [];
119
- _gaq.push(['_setAccount', 'UA-11356145-2']);
120
- _gaq.push(['_trackPageview']);
121
-
122
- (function() {
123
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
124
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
125
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
126
- })();
127
-
128
- </script>
129
- EOS
130
-
131
- Dir["doc/**/*.html"].each do |path|
132
- lines = IO.readlines(path)
133
-
134
- File.open(path, "w") do |file|
135
- lines.each do |line|
136
- if line.include?("</head>")
137
- file.write(google_analytics)
138
- end
139
-
140
- file.write(line)
141
- end
142
- end
143
- end
144
- end
145
-
146
- task :deploy do
147
- system "rsync --del -avz doc/ redis-rb.keyvalue.org:deploys/redis-rb.keyvalue.org/"
148
- end
149
- end
150
-
151
- class Source
152
-
153
- MATCHER = "(?:\\s{%d}#[^\\n]*\\n)*^\\s{%d}def ([a-z_?]+)(?:\(.*?\))?\\n.*?^\\s{%d}end\\n\\n"
154
-
155
- def initialize(data, options = {})
156
- @doc = parse(File.read(data), options)
157
- end
158
-
159
- def methods
160
- @doc.select do |d|
161
- d.is_a?(Method)
162
- end.map do |d|
163
- d.name
164
- end
165
- end
166
-
167
- def move(a, b)
168
- ao = @doc.find { |m| m.is_a?(Method) && m.name == a }
169
- bo = @doc.find { |m| m.is_a?(Method) && m.name == b }
170
- ai = @doc.index(ao)
171
- bi = @doc.index(bo)
172
-
173
- @doc.delete_at(ai)
174
- @doc.insert(bi, ao)
175
-
176
- nil
177
- end
178
-
179
- def to_s
180
- @doc.join
181
- end
182
-
183
- protected
184
-
185
- def parse(data, options = {})
186
- re = Regexp.new(MATCHER % ([options[:indent]] * 3), Regexp::MULTILINE)
187
- tail = data.dup
188
- doc = []
189
-
190
- while match = re.match(tail)
191
- doc << match.pre_match
192
- doc << Method.new(match)
193
- tail = match.post_match
194
- end
195
-
196
- doc << tail if tail
197
- doc
198
- end
199
-
200
- class Method
201
-
202
- def initialize(match)
203
- @match = match
204
- end
205
-
206
- def name
207
- @match[1]
208
- end
209
-
210
- def to_s
211
- @match[0]
212
- end
213
- end
214
- end
215
-
216
- namespace :commands do
217
- def redis_commands
218
- $redis_commands ||= doc.keys.map do |key|
219
- key.split(" ").first.downcase
220
- end.uniq
221
- end
222
-
223
- def doc
224
- $doc ||= begin
225
- require "open-uri"
226
- require "json"
227
-
228
- JSON.parse(open("https://github.com/antirez/redis-doc/raw/master/commands.json").read)
229
- end
230
- end
231
-
232
- task :order do
233
- require "json"
234
-
235
- reference = if File.exist?(".order")
236
- JSON.parse(File.read(".order"))
237
- else
238
- {}
239
- end
240
-
241
- buckets = {}
242
- doc.each do |k, v|
243
- buckets[v["group"]] ||= []
244
- buckets[v["group"]] << k.split.first.downcase
245
- buckets[v["group"]].uniq!
246
- end
247
-
248
- result = (reference.keys + (buckets.keys - reference.keys)).map do |g|
249
- [g, reference[g] + (buckets[g] - reference[g])]
250
- end
251
-
252
- File.open(".order", "w") do |f|
253
- f.write(JSON.pretty_generate(Hash[result]))
254
- end
255
- end
256
-
257
- def reorder(file, options = {})
258
- require "json"
259
- require "set"
260
-
261
- STDERR.puts "reordering #{file}..."
262
-
263
- reference = if File.exist?(".order")
264
- JSON.parse(File.read(".order"))
265
- else
266
- {}
267
- end
268
-
269
- dst = Source.new(file, options)
270
-
271
- src_methods = reference.map { |k, v| v }.flatten
272
- dst_methods = dst.methods
273
-
274
- src_set = Set.new(src_methods)
275
- dst_set = Set.new(dst_methods)
276
-
277
- intersection = src_set & dst_set
278
- intersection.delete("initialize")
279
-
280
- loop do
281
- src_methods = reference.map { |k, v| v }.flatten
282
- dst_methods = dst.methods
283
-
284
- src_methods = src_methods.select do |m|
285
- intersection.include?(m)
286
- end
287
-
288
- dst_methods = dst_methods.select do |m|
289
- intersection.include?(m)
290
- end
291
-
292
- if src_methods == dst_methods
293
- break
294
- end
295
-
296
- rv = yield(src_methods, dst_methods, dst)
297
- break if rv == false
298
- end
299
-
300
- File.open(file, "w") do |f|
301
- f.write(dst.to_s)
302
- end
303
- end
304
-
305
- task :reorder do
306
- blk = lambda do |src_methods, dst_methods, dst|
307
- src_methods.zip(dst_methods).each do |a, b|
308
- if a != b
309
- dst.move(a, b)
310
- break
311
- end
312
- end
313
- end
314
-
315
- reorder "lib/redis.rb", :indent => 2, &blk
316
- reorder "lib/redis/distributed.rb", :indent => 4, &blk
317
- end
318
-
319
- def missing(file, options = {})
320
- src = Source.new(file, options)
321
-
322
- defined_methods = src.methods.map(&:downcase)
323
- required_methods = redis_commands.map(&:downcase)
324
-
325
- STDOUT.puts "missing in #{file}:"
326
- STDOUT.puts (required_methods - defined_methods).inspect
327
- end
328
-
329
- task :missing do
330
- missing "lib/redis.rb", :indent => 2
331
- missing "lib/redis/distributed.rb", :indent => 4
332
- end
333
-
334
- def document(file)
335
- source = File.read(file)
336
-
337
- doc.each do |name, command|
338
- source.sub!(/(?:^ *# .*\n)*(^ *#\n(^ *# .+?\n)*)*^( *)def #{name.downcase}(\(|$)/) do
339
- extra_comments, indent, extra_args = $1, $3, $4
340
- comment = "#{indent}# #{command["summary"].strip}."
341
-
342
- IO.popen("par p#{2 + indent.size} 80", "r+") do |io|
343
- io.puts comment
344
- io.close_write
345
- comment = io.read
346
- end
347
-
348
- "#{comment}#{extra_comments}#{indent}def #{name.downcase}#{extra_args}"
349
- end
350
- end
351
-
352
- File.open(file, "w") { |f| f.write(source) }
353
- end
354
-
355
- task :doc do
356
- document "lib/redis.rb"
357
- document "lib/redis/distributed.rb"
358
- end
359
-
360
- task :verify do
361
- require "redis"
362
- require "stringio"
363
-
364
- require "./test/helper"
365
-
366
- OPTIONS[:logger] = Logger.new("./tmp/log")
367
-
368
- Rake::Task["test:ruby"].invoke
369
-
370
- redis = Redis.new
371
-
372
- report = ["Command", "\033[0mDefined?\033[0m", "\033[0mTested?\033[0m"]
373
-
374
- yes, no = "\033[1;32mYes\033[0m", "\033[1;31mNo\033[0m"
375
-
376
- log = File.read("./tmp/log")
377
-
378
- redis_commands.sort.each do |name, _|
379
- defined, tested = redis.respond_to?(name), log[">> #{name.upcase}"]
380
-
381
- next if defined && tested
382
-
383
- report << name
384
- report << (defined ? yes : no)
385
- report << (tested ? yes : no)
386
- end
387
-
388
- IO.popen("rs 0 3", "w") do |io|
389
- io.puts report.join("\n")
390
- end
391
- end
392
- end