redis 3.0.0 → 4.5.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 (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +315 -0
  3. data/README.md +301 -58
  4. data/lib/redis/client.rb +383 -88
  5. data/lib/redis/cluster/command.rb +81 -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 +108 -0
  9. data/lib/redis/cluster/node_key.rb +31 -0
  10. data/lib/redis/cluster/node_loader.rb +37 -0
  11. data/lib/redis/cluster/option.rb +93 -0
  12. data/lib/redis/cluster/slot.rb +86 -0
  13. data/lib/redis/cluster/slot_loader.rb +49 -0
  14. data/lib/redis/cluster.rb +291 -0
  15. data/lib/redis/connection/command_helper.rb +7 -10
  16. data/lib/redis/connection/hiredis.rb +12 -8
  17. data/lib/redis/connection/registry.rb +2 -1
  18. data/lib/redis/connection/ruby.rb +266 -74
  19. data/lib/redis/connection/synchrony.rb +41 -14
  20. data/lib/redis/connection.rb +4 -2
  21. data/lib/redis/distributed.rb +258 -76
  22. data/lib/redis/errors.rb +48 -0
  23. data/lib/redis/hash_ring.rb +31 -73
  24. data/lib/redis/pipeline.rb +74 -18
  25. data/lib/redis/subscribe.rb +24 -13
  26. data/lib/redis/version.rb +3 -1
  27. data/lib/redis.rb +2068 -464
  28. metadata +63 -160
  29. data/.gitignore +0 -10
  30. data/.order +0 -169
  31. data/.travis/Gemfile +0 -11
  32. data/.travis.yml +0 -50
  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,52 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedKeyTags < Test::Unit::TestCase
6
-
7
- include Helper
8
- include Helper::Distributed
9
-
10
- def test_hashes_consistently
11
- r1 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
12
- r2 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
13
- r3 = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
14
-
15
- assert_equal r1.node_for("foo").id, r2.node_for("foo").id
16
- assert_equal r1.node_for("foo").id, r3.node_for("foo").id
17
- end
18
-
19
- def test_allows_clustering_of_keys
20
- r = Redis::Distributed.new(NODES)
21
- r.add_node("redis://localhost:#{PORT}/14")
22
- r.flushdb
23
-
24
- 100.times do |i|
25
- r.set "{foo}users:#{i}", i
26
- end
27
-
28
- assert_equal [0, 100], r.nodes.map { |node| node.keys.size }
29
- end
30
-
31
- def test_distributes_keys_if_no_clustering_is_used
32
- r.add_node("redis://localhost:#{PORT}/14")
33
- r.flushdb
34
-
35
- r.set "users:1", 1
36
- r.set "users:4", 4
37
-
38
- assert_equal [1, 1], r.nodes.map { |node| node.keys.size }
39
- end
40
-
41
- def test_allows_passing_a_custom_tag_extractor
42
- r = Redis::Distributed.new(NODES, :tag => /^(.+?):/)
43
- r.add_node("redis://localhost:#{PORT}/14")
44
- r.flushdb
45
-
46
- 100.times do |i|
47
- r.set "foo:users:#{i}", i
48
- end
49
-
50
- assert_equal [0, 100], r.nodes.map { |node| node.keys.size }
51
- end
52
- end
@@ -1,26 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedPersistenceControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def test_save
10
- redis_mock(:save => lambda { "+SAVE" }) do |redis|
11
- assert_equal ["SAVE"], redis.save
12
- end
13
- end
14
-
15
- def test_bgsave
16
- redis_mock(:bgsave => lambda { "+BGSAVE" }) do |redis|
17
- assert_equal ["BGSAVE"], redis.bgsave
18
- end
19
- end
20
-
21
- def test_lastsave
22
- redis_mock(:lastsave => lambda { "+LASTSAVE" }) do |redis|
23
- assert_equal ["LASTSAVE"], redis.lastsave
24
- end
25
- end
26
- end
@@ -1,92 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedPublishSubscribe < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def test_subscribe_and_unsubscribe
10
- assert_raise Redis::Distributed::CannotDistribute do
11
- r.subscribe("foo", "bar") { }
12
- end
13
-
14
- assert_raise Redis::Distributed::CannotDistribute do
15
- r.subscribe("{qux}foo", "bar") { }
16
- end
17
- end
18
-
19
- def test_subscribe_and_unsubscribe_with_tags
20
- @subscribed = false
21
- @unsubscribed = false
22
-
23
- wire = Wire.new do
24
- r.subscribe("foo") do |on|
25
- on.subscribe do |channel, total|
26
- @subscribed = true
27
- @t1 = total
28
- end
29
-
30
- on.message do |channel, message|
31
- if message == "s1"
32
- r.unsubscribe
33
- @message = message
34
- end
35
- end
36
-
37
- on.unsubscribe do |channel, total|
38
- @unsubscribed = true
39
- @t2 = total
40
- end
41
- end
42
- end
43
-
44
- # Wait until the subscription is active before publishing
45
- Wire.pass while !@subscribed
46
-
47
- Redis::Distributed.new(NODES).publish("foo", "s1")
48
-
49
- wire.join
50
-
51
- assert @subscribed
52
- assert_equal 1, @t1
53
- assert @unsubscribed
54
- assert_equal 0, @t2
55
- assert_equal "s1", @message
56
- end
57
-
58
- def test_subscribe_within_subscribe
59
- @channels = []
60
-
61
- wire = Wire.new do
62
- r.subscribe("foo") do |on|
63
- on.subscribe do |channel, total|
64
- @channels << channel
65
-
66
- r.subscribe("bar") if channel == "foo"
67
- r.unsubscribe if channel == "bar"
68
- end
69
- end
70
- end
71
-
72
- wire.join
73
-
74
- assert_equal ["foo", "bar"], @channels
75
- end
76
-
77
- def test_other_commands_within_a_subscribe
78
- assert_raise Redis::CommandError do
79
- r.subscribe("foo") do |on|
80
- on.subscribe do |channel, total|
81
- r.set("bar", "s2")
82
- end
83
- end
84
- end
85
- end
86
-
87
- def test_subscribe_without_a_block
88
- assert_raise LocalJumpError do
89
- r.subscribe("foo")
90
- end
91
- end
92
- end
@@ -1,53 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedRemoteServerControlCommands < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def test_info
10
- %w(last_save_time redis_version total_connections_received connected_clients total_commands_processed connected_slaves uptime_in_seconds used_memory uptime_in_days changes_since_last_save).each do |x|
11
- r.info.each do |info|
12
- assert info.keys.include?(x)
13
- end
14
- end
15
- end
16
-
17
- def test_info_commandstats
18
- return if version < "2.9.0"
19
-
20
- r.nodes.each { |n| n.config(:resetstat) }
21
- r.ping # Executed on every node
22
-
23
- r.info(:commandstats).each do |info|
24
- assert_equal "1", info["ping"]["calls"]
25
- end
26
- end
27
-
28
- def test_monitor
29
- begin
30
- r.monitor
31
- rescue Exception => ex
32
- ensure
33
- assert ex.kind_of?(NotImplementedError)
34
- end
35
- end
36
-
37
- def test_echo
38
- assert_equal ["foo bar baz\n"], r.echo("foo bar baz\n")
39
- end
40
-
41
- def test_time
42
- return if version < "2.5.4"
43
-
44
- # Test that the difference between the time that Ruby reports and the time
45
- # that Redis reports is minimal (prevents the test from being racy).
46
- r.time.each do |rv|
47
- redis_usec = rv[0] * 1_000_000 + rv[1]
48
- ruby_usec = Integer(Time.now.to_f * 1_000_000)
49
-
50
- assert 500_000 > (ruby_usec - redis_usec).abs
51
- end
52
- end
53
- end
@@ -1,102 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedScripting < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def to_sha(script)
10
- r.script(:load, script).first
11
- end
12
-
13
- def test_script_exists
14
- return if version < "2.5.9" # 2.6-rc1
15
-
16
- a = to_sha("return 1")
17
- b = a.succ
18
-
19
- assert_equal [true], r.script(:exists, a)
20
- assert_equal [false], r.script(:exists, b)
21
- assert_equal [[true]], r.script(:exists, [a])
22
- assert_equal [[false]], r.script(:exists, [b])
23
- assert_equal [[true, false]], r.script(:exists, [a, b])
24
- end
25
-
26
- def test_script_flush
27
- return if version < "2.5.9" # 2.6-rc1
28
-
29
- sha = to_sha("return 1")
30
- assert r.script(:exists, sha).first
31
- assert_equal ["OK"], r.script(:flush)
32
- assert !r.script(:exists, sha).first
33
- end
34
-
35
- def test_script_kill
36
- return if version < "2.5.9" # 2.6-rc1
37
-
38
- redis_mock(:script => lambda { |arg| "+#{arg.upcase}" }) do |redis|
39
- assert_equal ["KILL"], redis.script(:kill)
40
- end
41
- end
42
-
43
- def test_eval
44
- return if version < "2.5.9" # 2.6-rc1
45
-
46
- assert_raises(Redis::Distributed::CannotDistribute) do
47
- r.eval("return #KEYS")
48
- end
49
-
50
- assert_raises(Redis::Distributed::CannotDistribute) do
51
- r.eval("return KEYS", ["k1", "k2"])
52
- end
53
-
54
- assert_equal ["k1"], r.eval("return KEYS", ["k1"])
55
- assert_equal ["a1", "a2"], r.eval("return ARGV", ["k1"], ["a1", "a2"])
56
- end
57
-
58
- def test_eval_with_options_hash
59
- return if version < "2.5.9" # 2.6-rc1
60
-
61
- assert_raises(Redis::Distributed::CannotDistribute) do
62
- r.eval("return #KEYS", {})
63
- end
64
-
65
- assert_raises(Redis::Distributed::CannotDistribute) do
66
- r.eval("return KEYS", { :keys => ["k1", "k2"] })
67
- end
68
-
69
- assert_equal ["k1"], r.eval("return KEYS", { :keys => ["k1"] })
70
- assert_equal ["a1", "a2"], r.eval("return ARGV", { :keys => ["k1"], :argv => ["a1", "a2"] })
71
- end
72
-
73
- def test_evalsha
74
- return if version < "2.5.9" # 2.6-rc1
75
-
76
- assert_raises(Redis::Distributed::CannotDistribute) do
77
- r.evalsha(to_sha("return #KEYS"))
78
- end
79
-
80
- assert_raises(Redis::Distributed::CannotDistribute) do
81
- r.evalsha(to_sha("return KEYS"), ["k1", "k2"])
82
- end
83
-
84
- assert_equal ["k1"], r.evalsha(to_sha("return KEYS"), ["k1"])
85
- assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), ["k1"], ["a1", "a2"])
86
- end
87
-
88
- def test_evalsha_with_options_hash
89
- return if version < "2.5.9" # 2.6-rc1
90
-
91
- assert_raises(Redis::Distributed::CannotDistribute) do
92
- r.evalsha(to_sha("return #KEYS"), {})
93
- end
94
-
95
- assert_raises(Redis::Distributed::CannotDistribute) do
96
- r.evalsha(to_sha("return KEYS"), { :keys => ["k1", "k2"] })
97
- end
98
-
99
- assert_equal ["k1"], r.evalsha(to_sha("return KEYS"), { :keys => ["k1"] })
100
- assert_equal ["a1", "a2"], r.evalsha(to_sha("return ARGV"), { :keys => ["k1"], :argv => ["a1", "a2"] })
101
- end
102
- end
@@ -1,20 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributedSorting < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def test_sort
10
- assert_raise(Redis::Distributed::CannotDistribute) do
11
- r.set("foo:1", "s1")
12
- r.set("foo:2", "s2")
13
-
14
- r.rpush("bar", "1")
15
- r.rpush("bar", "2")
16
-
17
- r.sort("bar", :get => "foo:*", :limit => [0, 1])
18
- end
19
- end
20
- end
@@ -1,58 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
4
-
5
- class TestDistributed < Test::Unit::TestCase
6
-
7
- include Helper::Distributed
8
-
9
- def test_handle_multiple_servers
10
- @r = Redis::Distributed.new ["redis://localhost:#{PORT}/15", *NODES]
11
-
12
- 100.times do |idx|
13
- @r.set(idx.to_s, "foo#{idx}")
14
- end
15
-
16
- 100.times do |idx|
17
- assert_equal "foo#{idx}", @r.get(idx.to_s)
18
- end
19
-
20
- assert_equal "0", @r.keys("*").sort.first
21
- assert_equal "string", @r.type("1")
22
- end
23
-
24
- def test_add_nodes
25
- logger = Logger.new("/dev/null")
26
-
27
- @r = Redis::Distributed.new NODES, :logger => logger, :timeout => 10
28
-
29
- assert_equal "127.0.0.1", @r.nodes[0].client.host
30
- assert_equal PORT, @r.nodes[0].client.port
31
- assert_equal 15, @r.nodes[0].client.db
32
- assert_equal 10, @r.nodes[0].client.timeout
33
- assert_equal logger, @r.nodes[0].client.logger
34
-
35
- @r.add_node("redis://localhost:6380/14")
36
-
37
- assert_equal "localhost", @r.nodes[1].client.host
38
- assert_equal 6380, @r.nodes[1].client.port
39
- assert_equal 14, @r.nodes[1].client.db
40
- assert_equal 10, @r.nodes[1].client.timeout
41
- assert_equal logger, @r.nodes[1].client.logger
42
- end
43
-
44
- def test_pipelining_commands_cannot_be_distributed
45
- assert_raise Redis::Distributed::CannotDistribute do
46
- r.pipelined do
47
- r.lpush "foo", "s1"
48
- r.lpush "foo", "s2"
49
- end
50
- end
51
- end
52
-
53
- def test_unknown_commands_does_not_work_by_default
54
- assert_raise NoMethodError do
55
- r.not_yet_implemented_command
56
- end
57
- end
58
- end
@@ -1,32 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "helper"
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 "helper"
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 "helper"
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
data/test/helper.rb DELETED
@@ -1,188 +0,0 @@
1
- $:.unshift File.expand_path('../lib', File.dirname(__FILE__))
2
-
3
- require "test/unit"
4
- require "logger"
5
- require "stringio"
6
-
7
- begin
8
- require "ruby-debug"
9
- rescue LoadError
10
- end
11
-
12
- $VERBOSE = true
13
-
14
- ENV["conn"] ||= "ruby"
15
-
16
- require "redis"
17
- require "redis/distributed"
18
- require "redis/connection/#{ENV["conn"]}"
19
-
20
- require "support/redis_mock"
21
- require "support/connection/#{ENV["conn"]}"
22
-
23
- PORT = 6381
24
- OPTIONS = {:port => PORT, :db => 15, :timeout => 0.1}
25
- NODES = ["redis://127.0.0.1:#{PORT}/15"]
26
-
27
- def init(redis)
28
- begin
29
- redis.select 14
30
- redis.flushdb
31
- redis.select 15
32
- redis.flushdb
33
- redis
34
- rescue Redis::CannotConnectError
35
- puts <<-EOS
36
-
37
- Cannot connect to Redis.
38
-
39
- Make sure Redis is running on localhost, port #{PORT}.
40
- This testing suite connects to the database 15.
41
-
42
- To install redis:
43
- visit <http://redis.io/download/>.
44
-
45
- To start the server:
46
- rake start
47
-
48
- To stop the server:
49
- rake stop
50
-
51
- EOS
52
- exit 1
53
- end
54
- end
55
-
56
- def driver(*drivers, &blk)
57
- if drivers.map(&:to_s).include?(ENV["conn"])
58
- class_eval(&blk)
59
- end
60
- end
61
-
62
- module Helper
63
-
64
- def run(runner)
65
- if respond_to?(:around)
66
- around { super(runner) }
67
- else
68
- super
69
- end
70
- end
71
-
72
- def silent
73
- verbose, $VERBOSE = $VERBOSE, false
74
-
75
- begin
76
- yield
77
- ensure
78
- $VERBOSE = verbose
79
- end
80
- end
81
-
82
- def with_external_encoding(encoding)
83
- original_encoding = Encoding.default_external
84
-
85
- begin
86
- silent { Encoding.default_external = Encoding.find(encoding) }
87
- yield
88
- ensure
89
- silent { Encoding.default_external = original_encoding }
90
- end
91
- end
92
-
93
- class Version
94
-
95
- include Comparable
96
-
97
- attr :parts
98
-
99
- def initialize(v)
100
- case v
101
- when Version
102
- @parts = v.parts
103
- else
104
- @parts = v.to_s.split(".")
105
- end
106
- end
107
-
108
- def <=>(other)
109
- other = Version.new(other)
110
- length = [self.parts.length, other.parts.length].max
111
- length.times do |i|
112
- a, b = self.parts[i], other.parts[i]
113
-
114
- return -1 if a.nil?
115
- return +1 if b.nil?
116
- return a <=> b if a != b
117
- end
118
-
119
- 0
120
- end
121
- end
122
-
123
- module Generic
124
-
125
- include Helper
126
-
127
- attr_reader :log
128
- attr_reader :redis
129
-
130
- alias :r :redis
131
-
132
- def setup
133
- @log = StringIO.new
134
- @redis = init _new_client
135
- end
136
-
137
- def teardown
138
- @redis.quit if @redis
139
- end
140
-
141
- def redis_mock(commands, options = {}, &blk)
142
- RedisMock.start(commands) do |port|
143
- yield _new_client(options.merge(:port => port))
144
- end
145
- end
146
- end
147
-
148
- module Client
149
-
150
- include Generic
151
-
152
- def version
153
- Version.new(redis.info["redis_version"])
154
- end
155
-
156
- private
157
-
158
- def _format_options(options)
159
- OPTIONS.merge(:logger => ::Logger.new(@log)).merge(options)
160
- end
161
-
162
- def _new_client(options = {})
163
- Redis.new(_format_options(options))
164
- end
165
- end
166
-
167
- module Distributed
168
-
169
- include Generic
170
-
171
- def version
172
- Version.new(redis.info.first["redis_version"])
173
- end
174
-
175
- private
176
-
177
- def _format_options(options)
178
- {
179
- :timeout => OPTIONS[:timeout],
180
- :logger => ::Logger.new(@log),
181
- }.merge(options)
182
- end
183
-
184
- def _new_client(options = {})
185
- Redis::Distributed.new(NODES, _format_options(options))
186
- end
187
- end
188
- end