redis 3.3.5 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +32 -50
  3. data/CHANGELOG.md +7 -9
  4. data/Gemfile +0 -1
  5. data/README.md +31 -75
  6. data/benchmarking/logging.rb +1 -1
  7. data/lib/redis.rb +31 -35
  8. data/lib/redis/client.rb +13 -8
  9. data/lib/redis/connection.rb +2 -2
  10. data/lib/redis/connection/command_helper.rb +2 -8
  11. data/lib/redis/connection/hiredis.rb +2 -2
  12. data/lib/redis/connection/ruby.rb +7 -27
  13. data/lib/redis/connection/synchrony.rb +3 -3
  14. data/lib/redis/pipeline.rb +0 -6
  15. data/lib/redis/version.rb +1 -1
  16. data/makefile +42 -0
  17. data/redis.gemspec +4 -8
  18. data/test/bitpos_test.rb +13 -19
  19. data/test/blocking_commands_test.rb +147 -6
  20. data/test/client_test.rb +1 -1
  21. data/test/command_map_test.rb +3 -5
  22. data/test/commands_on_hashes_test.rb +158 -5
  23. data/test/commands_on_hyper_log_log_test.rb +55 -6
  24. data/test/commands_on_lists_test.rb +139 -5
  25. data/test/commands_on_sets_test.rb +136 -5
  26. data/test/commands_on_sorted_sets_test.rb +312 -5
  27. data/test/commands_on_strings_test.rb +243 -6
  28. data/test/commands_on_value_types_test.rb +120 -7
  29. data/test/connection_handling_test.rb +5 -7
  30. data/test/encoding_test.rb +4 -8
  31. data/test/error_replies_test.rb +2 -4
  32. data/test/fork_safety_test.rb +1 -6
  33. data/test/helper.rb +9 -62
  34. data/test/helper_test.rb +1 -3
  35. data/test/internals_test.rb +67 -49
  36. data/test/persistence_control_commands_test.rb +1 -3
  37. data/test/pipelining_commands_test.rb +4 -8
  38. data/test/publish_subscribe_test.rb +1 -3
  39. data/test/remote_server_control_commands_test.rb +61 -4
  40. data/test/scanning_test.rb +1 -7
  41. data/test/scripting_test.rb +1 -3
  42. data/test/sentinel_command_test.rb +1 -3
  43. data/test/sentinel_test.rb +1 -3
  44. data/test/sorting_test.rb +1 -3
  45. data/test/ssl_test.rb +45 -49
  46. data/test/support/connection/hiredis.rb +1 -1
  47. data/test/support/connection/ruby.rb +1 -1
  48. data/test/support/connection/synchrony.rb +1 -1
  49. data/test/synchrony_driver.rb +6 -9
  50. data/test/thread_safety_test.rb +1 -3
  51. data/test/transactions_test.rb +1 -3
  52. data/test/unknown_commands_test.rb +1 -3
  53. data/test/url_param_test.rb +44 -46
  54. metadata +31 -77
  55. data/Rakefile +0 -87
  56. data/examples/dist_redis.rb +0 -43
  57. data/lib/redis/distributed.rb +0 -873
  58. data/lib/redis/hash_ring.rb +0 -132
  59. data/test/connection_test.rb +0 -57
  60. data/test/distributed_blocking_commands_test.rb +0 -46
  61. data/test/distributed_commands_on_hashes_test.rb +0 -10
  62. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  63. data/test/distributed_commands_on_lists_test.rb +0 -22
  64. data/test/distributed_commands_on_sets_test.rb +0 -83
  65. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  66. data/test/distributed_commands_on_strings_test.rb +0 -59
  67. data/test/distributed_commands_on_value_types_test.rb +0 -95
  68. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  69. data/test/distributed_connection_handling_test.rb +0 -23
  70. data/test/distributed_internals_test.rb +0 -79
  71. data/test/distributed_key_tags_test.rb +0 -52
  72. data/test/distributed_persistence_control_commands_test.rb +0 -26
  73. data/test/distributed_publish_subscribe_test.rb +0 -92
  74. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  75. data/test/distributed_scripting_test.rb +0 -102
  76. data/test/distributed_sorting_test.rb +0 -20
  77. data/test/distributed_test.rb +0 -58
  78. data/test/distributed_transactions_test.rb +0 -32
  79. data/test/lint/blocking_commands.rb +0 -150
  80. data/test/lint/hashes.rb +0 -162
  81. data/test/lint/hyper_log_log.rb +0 -60
  82. data/test/lint/lists.rb +0 -143
  83. data/test/lint/sets.rb +0 -140
  84. data/test/lint/sorted_sets.rb +0 -316
  85. data/test/lint/strings.rb +0 -260
  86. data/test/lint/value_types.rb +0 -122
@@ -1,132 +0,0 @@
1
- require 'zlib'
2
-
3
- class Redis
4
- class HashRing
5
-
6
- POINTS_PER_SERVER = 160 # this is the default in libmemcached
7
-
8
- attr_reader :ring, :sorted_keys, :replicas, :nodes
9
-
10
- # nodes is a list of objects that have a proper to_s representation.
11
- # replicas indicates how many virtual points should be used pr. node,
12
- # replicas are required to improve the distribution.
13
- def initialize(nodes=[], replicas=POINTS_PER_SERVER)
14
- @replicas = replicas
15
- @ring = {}
16
- @nodes = []
17
- @sorted_keys = []
18
- nodes.each do |node|
19
- add_node(node)
20
- end
21
- end
22
-
23
- # Adds a `node` to the hash ring (including a number of replicas).
24
- def add_node(node)
25
- @nodes << node
26
- @replicas.times do |i|
27
- key = Zlib.crc32("#{node.id}:#{i}")
28
- raise "Node ID collision" if @ring.has_key?(key)
29
- @ring[key] = node
30
- @sorted_keys << key
31
- end
32
- @sorted_keys.sort!
33
- end
34
-
35
- def remove_node(node)
36
- @nodes.reject!{|n| n.id == node.id}
37
- @replicas.times do |i|
38
- key = Zlib.crc32("#{node.id}:#{i}")
39
- @ring.delete(key)
40
- @sorted_keys.reject! {|k| k == key}
41
- end
42
- end
43
-
44
- # get the node in the hash ring for this key
45
- def get_node(key)
46
- get_node_pos(key)[0]
47
- end
48
-
49
- def get_node_pos(key)
50
- return [nil,nil] if @ring.size == 0
51
- crc = Zlib.crc32(key)
52
- idx = HashRing.binary_search(@sorted_keys, crc)
53
- return [@ring[@sorted_keys[idx]], idx]
54
- end
55
-
56
- def iter_nodes(key)
57
- return [nil,nil] if @ring.size == 0
58
- _, pos = get_node_pos(key)
59
- @ring.size.times do |n|
60
- yield @ring[@sorted_keys[(pos+n) % @ring.size]]
61
- end
62
- end
63
-
64
- class << self
65
-
66
- # gem install RubyInline to use this code
67
- # Native extension to perform the binary search within the hashring.
68
- # There's a pure ruby version below so this is purely optional
69
- # for performance. In testing 20k gets and sets, the native
70
- # binary search shaved about 12% off the runtime (9sec -> 8sec).
71
- begin
72
- require 'inline'
73
- inline do |builder|
74
- builder.c <<-EOM
75
- int binary_search(VALUE ary, unsigned int r) {
76
- int upper = RARRAY_LEN(ary) - 1;
77
- int lower = 0;
78
- int idx = 0;
79
-
80
- while (lower <= upper) {
81
- idx = (lower + upper) / 2;
82
-
83
- VALUE continuumValue = RARRAY_PTR(ary)[idx];
84
- unsigned int l = NUM2UINT(continuumValue);
85
- if (l == r) {
86
- return idx;
87
- }
88
- else if (l > r) {
89
- upper = idx - 1;
90
- }
91
- else {
92
- lower = idx + 1;
93
- }
94
- }
95
- if (upper < 0) {
96
- upper = RARRAY_LEN(ary) - 1;
97
- }
98
- return upper;
99
- }
100
- EOM
101
- end
102
- rescue Exception
103
- # Find the closest index in HashRing with value <= the given value
104
- def binary_search(ary, value, &block)
105
- upper = ary.size - 1
106
- lower = 0
107
- idx = 0
108
-
109
- while(lower <= upper) do
110
- idx = (lower + upper) / 2
111
- comp = ary[idx] <=> value
112
-
113
- if comp == 0
114
- return idx
115
- elsif comp > 0
116
- upper = idx - 1
117
- else
118
- lower = idx + 1
119
- end
120
- end
121
-
122
- if upper < 0
123
- upper = ary.size - 1
124
- end
125
- return upper
126
- end
127
-
128
- end
129
- end
130
-
131
- end
132
- end
@@ -1,57 +0,0 @@
1
- require_relative "helper"
2
-
3
- class TestConnection < Test::Unit::TestCase
4
-
5
- include Helper::Client
6
-
7
- def test_provides_a_meaningful_inspect
8
- assert_equal "#<Redis client v#{Redis::VERSION} for redis://127.0.0.1:#{PORT}/15>", r.inspect
9
- end
10
-
11
- def test_connection_information
12
- assert_equal "127.0.0.1", r.connection.fetch(:host)
13
- assert_equal 6381, r.connection.fetch(:port)
14
- assert_equal 15, r.connection.fetch(:db)
15
- assert_equal "127.0.0.1:6381", r.connection.fetch(:location)
16
- assert_equal "redis://127.0.0.1:6381/15", r.connection.fetch(:id)
17
- end
18
-
19
- def test_default_id_with_host_and_port
20
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0))
21
- assert_equal "redis://host:1234/0", redis.connection.fetch(:id)
22
- end
23
-
24
- def test_default_id_with_host_and_port_and_explicit_scheme
25
- redis = Redis.new(OPTIONS.merge(:host => "host", :port => "1234", :db => 0, :scheme => "foo"))
26
- assert_equal "redis://host:1234/0", redis.connection.fetch(:id)
27
- end
28
-
29
- def test_default_id_with_path
30
- redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0))
31
- assert_equal "redis:///tmp/redis.sock/0", redis.connection.fetch(:id)
32
- end
33
-
34
- def test_default_id_with_path_and_explicit_scheme
35
- redis = Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock", :db => 0, :scheme => "foo"))
36
- assert_equal "redis:///tmp/redis.sock/0", redis.connection.fetch(:id)
37
- end
38
-
39
- def test_override_id
40
- redis = Redis.new(OPTIONS.merge(:id => "test"))
41
- assert_equal "test", redis.connection.fetch(:id)
42
- end
43
-
44
- def test_id_inside_multi
45
- redis = Redis.new(OPTIONS)
46
- id = nil
47
- connection_id = nil
48
-
49
- redis.multi do
50
- id = redis.id
51
- connection_id = redis.connection.fetch(:id)
52
- end
53
-
54
- assert_equal "redis://127.0.0.1:6381/15", id
55
- assert_equal "redis://127.0.0.1:6381/15", connection_id
56
- end
57
- end
@@ -1,46 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/blocking_commands"
5
-
6
- class TestDistributedBlockingCommands < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::BlockingCommands
10
-
11
- def test_blpop_raises
12
- assert_raises(Redis::Distributed::CannotDistribute) do
13
- r.blpop(["foo", "bar"])
14
- end
15
- end
16
-
17
- def test_blpop_raises_with_old_prototype
18
- assert_raises(Redis::Distributed::CannotDistribute) do
19
- r.blpop("foo", "bar", 0)
20
- end
21
- end
22
-
23
- def test_brpop_raises
24
- assert_raises(Redis::Distributed::CannotDistribute) do
25
- r.brpop(["foo", "bar"])
26
- end
27
- end
28
-
29
- def test_brpop_raises_with_old_prototype
30
- assert_raises(Redis::Distributed::CannotDistribute) do
31
- r.brpop("foo", "bar", 0)
32
- end
33
- end
34
-
35
- def test_brpoplpush_raises
36
- assert_raises(Redis::Distributed::CannotDistribute) do
37
- r.brpoplpush("foo", "bar")
38
- end
39
- end
40
-
41
- def test_brpoplpush_raises_with_old_prototype
42
- assert_raises(Redis::Distributed::CannotDistribute) do
43
- r.brpoplpush("foo", "bar", 0)
44
- end
45
- end
46
- end
@@ -1,10 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hashes"
5
-
6
- class TestDistributedCommandsOnHashes < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::Hashes
10
- end
@@ -1,33 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hyper_log_log"
5
-
6
- class TestDistributedCommandsOnHyperLogLog < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::HyperLogLog
10
-
11
- def test_pfmerge
12
- target_version "2.8.9" do
13
- assert_raise Redis::Distributed::CannotDistribute do
14
- r.pfadd "foo", "s1"
15
- r.pfadd "bar", "s2"
16
-
17
- assert r.pfmerge("res", "foo", "bar")
18
- end
19
- end
20
- end
21
-
22
- def test_pfcount_multiple_keys_diff_nodes
23
- target_version "2.8.9" do
24
- assert_raise Redis::Distributed::CannotDistribute do
25
- r.pfadd "foo", "s1"
26
- r.pfadd "bar", "s2"
27
-
28
- assert r.pfcount("res", "foo", "bar")
29
- end
30
- end
31
- end
32
-
33
- end
@@ -1,22 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/lists"
5
-
6
- class TestDistributedCommandsOnLists < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::Lists
10
-
11
- def test_rpoplpush
12
- assert_raise Redis::Distributed::CannotDistribute do
13
- r.rpoplpush("foo", "bar")
14
- end
15
- end
16
-
17
- def test_brpoplpush
18
- assert_raise Redis::Distributed::CannotDistribute do
19
- r.brpoplpush("foo", "bar", :timeout => 1)
20
- end
21
- end
22
- end
@@ -1,83 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/sets"
5
-
6
- class TestDistributedCommandsOnSets < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::Sets
10
-
11
- def test_smove
12
- assert_raise Redis::Distributed::CannotDistribute do
13
- r.sadd "foo", "s1"
14
- r.sadd "bar", "s2"
15
-
16
- r.smove("foo", "bar", "s1")
17
- end
18
- end
19
-
20
- def test_sinter
21
- assert_raise Redis::Distributed::CannotDistribute do
22
- r.sadd "foo", "s1"
23
- r.sadd "foo", "s2"
24
- r.sadd "bar", "s2"
25
-
26
- r.sinter("foo", "bar")
27
- end
28
- end
29
-
30
- def test_sinterstore
31
- assert_raise Redis::Distributed::CannotDistribute do
32
- r.sadd "foo", "s1"
33
- r.sadd "foo", "s2"
34
- r.sadd "bar", "s2"
35
-
36
- r.sinterstore("baz", "foo", "bar")
37
- end
38
- end
39
-
40
- def test_sunion
41
- assert_raise Redis::Distributed::CannotDistribute do
42
- r.sadd "foo", "s1"
43
- r.sadd "foo", "s2"
44
- r.sadd "bar", "s2"
45
- r.sadd "bar", "s3"
46
-
47
- r.sunion("foo", "bar")
48
- end
49
- end
50
-
51
- def test_sunionstore
52
- assert_raise Redis::Distributed::CannotDistribute do
53
- r.sadd "foo", "s1"
54
- r.sadd "foo", "s2"
55
- r.sadd "bar", "s2"
56
- r.sadd "bar", "s3"
57
-
58
- r.sunionstore("baz", "foo", "bar")
59
- end
60
- end
61
-
62
- def test_sdiff
63
- assert_raise Redis::Distributed::CannotDistribute do
64
- r.sadd "foo", "s1"
65
- r.sadd "foo", "s2"
66
- r.sadd "bar", "s2"
67
- r.sadd "bar", "s3"
68
-
69
- r.sdiff("foo", "bar")
70
- end
71
- end
72
-
73
- def test_sdiffstore
74
- assert_raise Redis::Distributed::CannotDistribute do
75
- r.sadd "foo", "s1"
76
- r.sadd "foo", "s2"
77
- r.sadd "bar", "s2"
78
- r.sadd "bar", "s3"
79
-
80
- r.sdiffstore("baz", "foo", "bar")
81
- end
82
- end
83
- end
@@ -1,18 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/sorted_sets"
5
-
6
- class TestDistributedCommandsOnSortedSets < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::SortedSets
10
-
11
- def test_zcount
12
- r.zadd "foo", 1, "s1"
13
- r.zadd "foo", 2, "s2"
14
- r.zadd "foo", 3, "s3"
15
-
16
- assert_equal 2, r.zcount("foo", 2, 3)
17
- end
18
- end
@@ -1,59 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/strings"
5
-
6
- class TestDistributedCommandsOnStrings < Test::Unit::TestCase
7
-
8
- include Helper::Distributed
9
- include Lint::Strings
10
-
11
- def test_mget
12
- assert_raise Redis::Distributed::CannotDistribute do
13
- r.mget("foo", "bar")
14
- end
15
- end
16
-
17
- def test_mget_mapped
18
- assert_raise Redis::Distributed::CannotDistribute do
19
- r.mapped_mget("foo", "bar")
20
- end
21
- end
22
-
23
- def test_mset
24
- assert_raise Redis::Distributed::CannotDistribute do
25
- r.mset(:foo, "s1", :bar, "s2")
26
- end
27
- end
28
-
29
- def test_mset_mapped
30
- assert_raise Redis::Distributed::CannotDistribute do
31
- r.mapped_mset(:foo => "s1", :bar => "s2")
32
- end
33
- end
34
-
35
- def test_msetnx
36
- assert_raise Redis::Distributed::CannotDistribute do
37
- r.set("foo", "s1")
38
- r.msetnx(:foo, "s2", :bar, "s3")
39
- end
40
- end
41
-
42
- def test_msetnx_mapped
43
- assert_raise Redis::Distributed::CannotDistribute do
44
- r.set("foo", "s1")
45
- r.mapped_msetnx(:foo => "s2", :bar => "s3")
46
- end
47
- end
48
-
49
- def test_bitop
50
- target_version "2.5.10" do
51
- assert_raise Redis::Distributed::CannotDistribute do
52
- r.set("foo", "a")
53
- r.set("bar", "b")
54
-
55
- r.bitop(:and, "foo&bar", "foo", "bar")
56
- end
57
- end
58
- end
59
- end