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,62 +0,0 @@
1
- # Run with
2
- #
3
- # $ ruby -Ilib benchmarking/logging.rb
4
- #
5
-
6
- begin
7
- require "bench"
8
- rescue LoadError
9
- $stderr.puts "`gem install bench` and try again."
10
- exit 1
11
- end
12
-
13
- require "redis"
14
- require "logger"
15
-
16
- def log(level, namespace = nil)
17
- logger = (namespace || Kernel).const_get(:Logger).new("/dev/null")
18
- logger.level = (namespace || Logger).const_get(level)
19
- logger
20
- end
21
-
22
- def stress(redis)
23
- redis.flushdb
24
-
25
- n = (ARGV.shift || 2000).to_i
26
-
27
- n.times do |i|
28
- key = "foo:#{i}"
29
- redis.set key, i
30
- redis.get key
31
- end
32
- end
33
-
34
- default = Redis.new
35
-
36
- logging_redises = [
37
- Redis.new(:logger => log(:DEBUG)),
38
- Redis.new(:logger => log(:INFO)),
39
- ]
40
-
41
- begin
42
- require "log4r"
43
-
44
- logging_redises += [
45
- Redis.new(:logger => log(:DEBUG, Log4r)),
46
- Redis.new(:logger => log(:INFO, Log4r)),
47
- ]
48
- rescue LoadError
49
- $stderr.puts "Log4r not installed. `gem install log4r` if you want to compare it against Ruby's Logger (spoiler: it's much faster)."
50
- end
51
-
52
- benchmark "Default options (no logger)" do
53
- stress(default)
54
- end
55
-
56
- logging_redises.each do |redis|
57
- benchmark "#{redis.client.logger.class} on #{Logger::SEV_LABEL[redis.client.logger.level]}" do
58
- stress(redis)
59
- end
60
- end
61
-
62
- run 10
@@ -1,51 +0,0 @@
1
- require "benchmark"
2
-
3
- $:.push File.join(File.dirname(__FILE__), 'lib')
4
-
5
- require 'redis'
6
-
7
- ITERATIONS = 10000
8
-
9
- @r = Redis.new
10
-
11
- Benchmark.bmbm do |benchmark|
12
- benchmark.report("set") do
13
- @r.flushdb
14
-
15
- ITERATIONS.times do |i|
16
- @r.set("foo#{i}", "Hello world!")
17
- @r.get("foo#{i}")
18
- end
19
- end
20
-
21
- benchmark.report("set (pipelined)") do
22
- @r.flushdb
23
-
24
- @r.pipelined do
25
- ITERATIONS.times do |i|
26
- @r.set("foo#{i}", "Hello world!")
27
- @r.get("foo#{i}")
28
- end
29
- end
30
- end
31
-
32
- benchmark.report("lpush+ltrim") do
33
- @r.flushdb
34
-
35
- ITERATIONS.times do |i|
36
- @r.lpush "lpush#{i}", i
37
- @r.ltrim "ltrim#{i}", 0, 30
38
- end
39
- end
40
-
41
- benchmark.report("lpush+ltrim (pipelined)") do
42
- @r.flushdb
43
-
44
- @r.pipelined do
45
- ITERATIONS.times do |i|
46
- @r.lpush "lpush#{i}", i
47
- @r.ltrim "ltrim#{i}", 0, 30
48
- end
49
- end
50
- end
51
- end
@@ -1,21 +0,0 @@
1
- # Run with
2
- #
3
- # $ ruby -Ilib benchmarking/speed.rb
4
- #
5
-
6
- require "benchmark"
7
- require "redis"
8
-
9
- r = Redis.new
10
- n = (ARGV.shift || 20000).to_i
11
-
12
- elapsed = Benchmark.realtime do
13
- # n sets, n gets
14
- n.times do |i|
15
- key = "foo#{i}"
16
- r[key] = key * 10
17
- r[key]
18
- end
19
- end
20
-
21
- puts '%.2f Kops' % (2 * n / 1000 / elapsed)
@@ -1,24 +0,0 @@
1
- require 'fileutils'
2
-
3
- def run_in_background(command)
4
- fork { system command }
5
- end
6
-
7
- def with_all_segments(&block)
8
- 0.upto(9) do |segment_number|
9
- block_size = 100000
10
- start_index = segment_number * block_size
11
- end_index = start_index + block_size - 1
12
- block.call(start_index, end_index)
13
- end
14
- end
15
-
16
- #with_all_segments do |start_index, end_index|
17
- # puts "Initializing keys from #{start_index} to #{end_index}"
18
- # system "ruby worker.rb initialize #{start_index} #{end_index} 0"
19
- #end
20
-
21
- with_all_segments do |start_index, end_index|
22
- run_in_background "ruby worker.rb write #{start_index} #{end_index} 10"
23
- run_in_background "ruby worker.rb read #{start_index} #{end_index} 1"
24
- end
@@ -1,71 +0,0 @@
1
- BENCHMARK_ROOT = File.dirname(__FILE__)
2
- REDIS_ROOT = File.join(BENCHMARK_ROOT, "..", "lib")
3
-
4
- $: << REDIS_ROOT
5
- require 'redis'
6
- require 'benchmark'
7
-
8
- def show_usage
9
- puts <<-EOL
10
- Usage: worker.rb [read:write] <start_index> <end_index> <sleep_msec>
11
- EOL
12
- end
13
-
14
- def shift_from_argv
15
- value = ARGV.shift
16
- unless value
17
- show_usage
18
- exit -1
19
- end
20
- value
21
- end
22
-
23
- operation = shift_from_argv.to_sym
24
- start_index = shift_from_argv.to_i
25
- end_index = shift_from_argv.to_i
26
- sleep_msec = shift_from_argv.to_i
27
- sleep_duration = sleep_msec/1000.0
28
-
29
- redis = Redis.new
30
-
31
- case operation
32
- when :initialize
33
-
34
- start_index.upto(end_index) do |i|
35
- redis[i] = 0
36
- end
37
-
38
- when :clear
39
-
40
- start_index.upto(end_index) do |i|
41
- redis.delete(i)
42
- end
43
-
44
- when :read, :write
45
-
46
- puts "Starting to #{operation} at segment #{end_index + 1}"
47
-
48
- loop do
49
- t1 = Time.now
50
- start_index.upto(end_index) do |i|
51
- case operation
52
- when :read
53
- redis.get(i)
54
- when :write
55
- redis.incr(i)
56
- else
57
- raise "Unknown operation: #{operation}"
58
- end
59
- sleep sleep_duration
60
- end
61
- t2 = Time.now
62
-
63
- requests_processed = end_index - start_index
64
- time = t2 - t1
65
- puts "#{t2.strftime("%H:%M")} [segment #{end_index + 1}] : Processed #{requests_processed} requests in #{time} seconds - #{(requests_processed/time).round} requests/sec"
66
- end
67
-
68
- else
69
- raise "Unknown operation: #{operation}"
70
- end
71
-
@@ -1,15 +0,0 @@
1
- require 'redis'
2
-
3
- r = Redis.new
4
-
5
- r.del('foo')
6
-
7
- puts
8
-
9
- p'set foo to "bar"'
10
- r['foo'] = 'bar'
11
-
12
- puts
13
-
14
- p 'value of foo'
15
- p r['foo']
@@ -1,43 +0,0 @@
1
- require "redis"
2
- require "redis/distributed"
3
-
4
- r = Redis::Distributed.new %w[redis://localhost:6379 redis://localhost:6380 redis://localhost:6381 redis://localhost:6382]
5
-
6
- r.flushdb
7
-
8
- r['urmom'] = 'urmom'
9
- r['urdad'] = 'urdad'
10
- r['urmom1'] = 'urmom1'
11
- r['urdad1'] = 'urdad1'
12
- r['urmom2'] = 'urmom2'
13
- r['urdad2'] = 'urdad2'
14
- r['urmom3'] = 'urmom3'
15
- r['urdad3'] = 'urdad3'
16
- p r['urmom']
17
- p r['urdad']
18
- p r['urmom1']
19
- p r['urdad1']
20
- p r['urmom2']
21
- p r['urdad2']
22
- p r['urmom3']
23
- p r['urdad3']
24
-
25
- r.rpush 'listor', 'foo1'
26
- r.rpush 'listor', 'foo2'
27
- r.rpush 'listor', 'foo3'
28
- r.rpush 'listor', 'foo4'
29
- r.rpush 'listor', 'foo5'
30
-
31
- p r.rpop('listor')
32
- p r.rpop('listor')
33
- p r.rpop('listor')
34
- p r.rpop('listor')
35
- p r.rpop('listor')
36
-
37
- puts "key distribution:"
38
-
39
- r.ring.nodes.each do |node|
40
- p [node.client, node.keys("*")]
41
- end
42
- r.flushdb
43
- p r.keys('*')
@@ -1,17 +0,0 @@
1
- require 'redis'
2
-
3
- r = Redis.new
4
-
5
- puts
6
- p 'incr'
7
- r.del 'counter'
8
-
9
- p r.incr('counter')
10
- p r.incr('counter')
11
- p r.incr('counter')
12
-
13
- puts
14
- p 'decr'
15
- p r.decr('counter')
16
- p r.decr('counter')
17
- p r.decr('counter')
@@ -1,26 +0,0 @@
1
- require 'rubygems'
2
- require 'redis'
3
-
4
- r = Redis.new
5
-
6
- r.del 'logs'
7
-
8
- puts
9
-
10
- p "pushing log messages into a LIST"
11
- r.rpush 'logs', 'some log message'
12
- r.rpush 'logs', 'another log message'
13
- r.rpush 'logs', 'yet another log message'
14
- r.rpush 'logs', 'also another log message'
15
-
16
- puts
17
- p 'contents of logs LIST'
18
-
19
- p r.lrange('logs', 0, -1)
20
-
21
- puts
22
- p 'Trim logs LIST to last 2 elements(easy circular buffer)'
23
-
24
- r.ltrim('logs', -2, -1)
25
-
26
- p r.lrange('logs', 0, -1)
@@ -1,31 +0,0 @@
1
- require "redis"
2
-
3
- puts <<-EOS
4
- To play with this example use redis-cli from another terminal, like this:
5
-
6
- $ redis-cli publish one hello
7
-
8
- Finally force the example to exit sending the 'exit' message with:
9
-
10
- $ redis-cli publish two exit
11
-
12
- EOS
13
-
14
- redis = Redis.new
15
-
16
- trap(:INT) { puts; exit }
17
-
18
- redis.subscribe(:one, :two) do |on|
19
- on.subscribe do |channel, subscriptions|
20
- puts "Subscribed to ##{channel} (#{subscriptions} subscriptions)"
21
- end
22
-
23
- on.message do |channel, message|
24
- puts "##{channel}: #{message}"
25
- redis.unsubscribe if message == "exit"
26
- end
27
-
28
- on.unsubscribe do |channel, subscriptions|
29
- puts "Unsubscribed from ##{channel} (#{subscriptions} subscriptions)"
30
- end
31
- end
@@ -1,36 +0,0 @@
1
- require 'rubygems'
2
- require 'redis'
3
-
4
- r = Redis.new
5
-
6
- r.del 'foo-tags'
7
- r.del 'bar-tags'
8
-
9
- puts
10
- p "create a set of tags on foo-tags"
11
-
12
- r.sadd 'foo-tags', 'one'
13
- r.sadd 'foo-tags', 'two'
14
- r.sadd 'foo-tags', 'three'
15
-
16
- puts
17
- p "create a set of tags on bar-tags"
18
-
19
- r.sadd 'bar-tags', 'three'
20
- r.sadd 'bar-tags', 'four'
21
- r.sadd 'bar-tags', 'five'
22
-
23
- puts
24
- p 'foo-tags'
25
-
26
- p r.smembers('foo-tags')
27
-
28
- puts
29
- p 'bar-tags'
30
-
31
- p r.smembers('bar-tags')
32
-
33
- puts
34
- p 'intersection of foo-tags and bar-tags'
35
-
36
- p r.sinter('foo-tags', 'bar-tags')
@@ -1,3 +0,0 @@
1
- run lambda { |env|
2
- [200, {"Content-Type" => "text/plain"}, [Redis.current.randomkey]]
3
- }
@@ -1,20 +0,0 @@
1
- require "redis"
2
-
3
- worker_processes 3
4
-
5
- # If you set the connection to Redis *before* forking,
6
- # you will cause forks to share a file descriptor.
7
- #
8
- # This causes a concurrency problem by which one fork
9
- # can read or write to the socket while others are
10
- # performing other operations.
11
- #
12
- # Most likely you'll be getting ProtocolError exceptions
13
- # mentioning a wrong initial byte in the reply.
14
- #
15
- # Thus we need to connect to Redis after forking the
16
- # worker processes.
17
-
18
- after_fork do |server, worker|
19
- Redis.current.quit
20
- end
@@ -1,41 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- $:.unshift File.expand_path("../lib", __FILE__)
4
-
5
- require "redis/version"
6
-
7
- Gem::Specification.new do |s|
8
- s.name = "redis"
9
-
10
- s.version = Redis::VERSION
11
-
12
- s.homepage = "https://github.com/redis/redis-rb"
13
-
14
- s.summary = "A Ruby client library for Redis"
15
-
16
- s.description = <<-EOS
17
- A Ruby client that tries to match Redis' API one-to-one, while still
18
- providing an idiomatic interface. It features thread-safety,
19
- client-side sharding, pipelining, and an obsession for performance.
20
- EOS
21
-
22
- s.authors = [
23
- "Ezra Zygmuntowicz",
24
- "Taylor Weibley",
25
- "Matthew Clark",
26
- "Brian McKinney",
27
- "Salvatore Sanfilippo",
28
- "Luca Guidi",
29
- "Michel Martens",
30
- "Damian Janowski",
31
- "Pieter Noordhuis"
32
- ]
33
-
34
- s.email = ["redis-db@googlegroups.com"]
35
-
36
- s.files = `git ls-files`.split("\n")
37
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
38
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
39
-
40
- s.add_development_dependency("rake")
41
- end