redis 3.0.0 → 4.2.2

Sign up to get free protection for your applications and to get access to all the features.
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