gorsuch-redis 3.0.0.rc1

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 (87) hide show
  1. data/.gitignore +10 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +113 -0
  4. data/LICENSE +20 -0
  5. data/README.md +214 -0
  6. data/Rakefile +260 -0
  7. data/TODO.md +4 -0
  8. data/benchmarking/logging.rb +62 -0
  9. data/benchmarking/pipeline.rb +51 -0
  10. data/benchmarking/speed.rb +21 -0
  11. data/benchmarking/suite.rb +24 -0
  12. data/benchmarking/thread_safety.rb +38 -0
  13. data/benchmarking/worker.rb +71 -0
  14. data/examples/basic.rb +15 -0
  15. data/examples/dist_redis.rb +43 -0
  16. data/examples/incr-decr.rb +17 -0
  17. data/examples/list.rb +26 -0
  18. data/examples/pubsub.rb +31 -0
  19. data/examples/sets.rb +36 -0
  20. data/examples/unicorn/config.ru +3 -0
  21. data/examples/unicorn/unicorn.rb +20 -0
  22. data/lib/redis/client.rb +303 -0
  23. data/lib/redis/connection/command_helper.rb +44 -0
  24. data/lib/redis/connection/hiredis.rb +52 -0
  25. data/lib/redis/connection/registry.rb +12 -0
  26. data/lib/redis/connection/ruby.rb +136 -0
  27. data/lib/redis/connection/synchrony.rb +131 -0
  28. data/lib/redis/connection.rb +9 -0
  29. data/lib/redis/distributed.rb +696 -0
  30. data/lib/redis/errors.rb +38 -0
  31. data/lib/redis/hash_ring.rb +131 -0
  32. data/lib/redis/pipeline.rb +106 -0
  33. data/lib/redis/subscribe.rb +79 -0
  34. data/lib/redis/version.rb +3 -0
  35. data/lib/redis.rb +1724 -0
  36. data/redis.gemspec +43 -0
  37. data/test/command_map_test.rb +29 -0
  38. data/test/commands_on_hashes_test.rb +20 -0
  39. data/test/commands_on_lists_test.rb +60 -0
  40. data/test/commands_on_sets_test.rb +76 -0
  41. data/test/commands_on_sorted_sets_test.rb +108 -0
  42. data/test/commands_on_strings_test.rb +80 -0
  43. data/test/commands_on_value_types_test.rb +87 -0
  44. data/test/connection_handling_test.rb +204 -0
  45. data/test/db/.gitignore +1 -0
  46. data/test/distributed_blocking_commands_test.rb +53 -0
  47. data/test/distributed_commands_on_hashes_test.rb +11 -0
  48. data/test/distributed_commands_on_lists_test.rb +23 -0
  49. data/test/distributed_commands_on_sets_test.rb +84 -0
  50. data/test/distributed_commands_on_sorted_sets_test.rb +19 -0
  51. data/test/distributed_commands_on_strings_test.rb +49 -0
  52. data/test/distributed_commands_on_value_types_test.rb +72 -0
  53. data/test/distributed_commands_requiring_clustering_test.rb +148 -0
  54. data/test/distributed_connection_handling_test.rb +24 -0
  55. data/test/distributed_internals_test.rb +27 -0
  56. data/test/distributed_key_tags_test.rb +52 -0
  57. data/test/distributed_persistence_control_commands_test.rb +23 -0
  58. data/test/distributed_publish_subscribe_test.rb +100 -0
  59. data/test/distributed_remote_server_control_commands_test.rb +42 -0
  60. data/test/distributed_sorting_test.rb +21 -0
  61. data/test/distributed_test.rb +59 -0
  62. data/test/distributed_transactions_test.rb +33 -0
  63. data/test/encoding_test.rb +15 -0
  64. data/test/error_replies_test.rb +53 -0
  65. data/test/helper.rb +155 -0
  66. data/test/helper_test.rb +8 -0
  67. data/test/internals_test.rb +152 -0
  68. data/test/lint/hashes.rb +140 -0
  69. data/test/lint/internals.rb +36 -0
  70. data/test/lint/lists.rb +107 -0
  71. data/test/lint/sets.rb +90 -0
  72. data/test/lint/sorted_sets.rb +196 -0
  73. data/test/lint/strings.rb +133 -0
  74. data/test/lint/value_types.rb +81 -0
  75. data/test/persistence_control_commands_test.rb +21 -0
  76. data/test/pipelining_commands_test.rb +186 -0
  77. data/test/publish_subscribe_test.rb +158 -0
  78. data/test/redis_mock.rb +89 -0
  79. data/test/remote_server_control_commands_test.rb +88 -0
  80. data/test/sorting_test.rb +43 -0
  81. data/test/synchrony_driver.rb +57 -0
  82. data/test/test.conf +9 -0
  83. data/test/thread_safety_test.rb +30 -0
  84. data/test/transactions_test.rb +173 -0
  85. data/test/unknown_commands_test.rb +13 -0
  86. data/test/url_param_test.rb +59 -0
  87. metadata +236 -0
@@ -0,0 +1,204 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require File.expand_path("./redis_mock", File.dirname(__FILE__))
5
+
6
+ include RedisMock::Helper
7
+
8
+ setup do
9
+ init Redis.new(OPTIONS)
10
+ end
11
+
12
+ test "AUTH" do
13
+ replies = {
14
+ :auth => lambda { |password| $auth = password; "+OK" },
15
+ :get => lambda { |key| $auth == "secret" ? "$3\r\nbar" : "$-1" },
16
+ }
17
+
18
+ redis_mock(replies) do
19
+ redis = Redis.new(OPTIONS.merge(:port => 6380, :password => "secret"))
20
+
21
+ assert "bar" == redis.get("foo")
22
+ end
23
+ end
24
+
25
+ test "PING" do |r|
26
+ assert "PONG" == r.ping
27
+ end
28
+
29
+ test "SELECT" do |r|
30
+ r.set "foo", "bar"
31
+
32
+ r.select 14
33
+ assert nil == r.get("foo")
34
+
35
+ r.client.disconnect
36
+
37
+ assert nil == r.get("foo")
38
+ end
39
+
40
+ test "QUIT" do |r|
41
+ r.quit
42
+
43
+ assert !r.client.connected?
44
+ end
45
+
46
+ test "SHUTDOWN" do
47
+ commands = {
48
+ :shutdown => lambda { :exit }
49
+ }
50
+
51
+ redis_mock(commands) do
52
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
53
+
54
+ # SHUTDOWN does not reply: test that it does not raise here.
55
+ assert nil == redis.shutdown
56
+ end
57
+ end
58
+
59
+ test "SHUTDOWN with error" do
60
+ connections = 0
61
+ commands = {
62
+ :select => lambda { |*_| connections += 1; "+OK\r\n" },
63
+ :connections => lambda { ":#{connections}\r\n" },
64
+ :shutdown => lambda { "-ERR could not shutdown\r\n" }
65
+ }
66
+
67
+ redis_mock(commands) do
68
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
69
+
70
+ connections = redis.connections
71
+
72
+ # SHUTDOWN replies with an error: test that it gets raised
73
+ assert_raise Redis::CommandError do
74
+ redis.shutdown
75
+ end
76
+
77
+ # The connection should remain in tact
78
+ assert connections == redis.connections
79
+ end
80
+ end
81
+
82
+ test "SHUTDOWN from pipeline" do
83
+ commands = {
84
+ :shutdown => lambda { :exit }
85
+ }
86
+
87
+ redis_mock(commands) do
88
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
89
+
90
+ result = redis.pipelined do
91
+ redis.shutdown
92
+ end
93
+
94
+ assert nil == result
95
+ assert !redis.client.connected?
96
+ end
97
+ end
98
+
99
+ test "SHUTDOWN with error from pipeline" do
100
+ connections = 0
101
+ commands = {
102
+ :select => lambda { |*_| connections += 1; "+OK\r\n" },
103
+ :connections => lambda { ":#{connections}\r\n" },
104
+ :shutdown => lambda { "-ERR could not shutdown\r\n" }
105
+ }
106
+
107
+ redis_mock(commands) do
108
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
109
+
110
+ connections = redis.connections
111
+
112
+ # SHUTDOWN replies with an error: test that it gets raised
113
+ assert_raise Redis::CommandError do
114
+ redis.pipelined do
115
+ redis.shutdown
116
+ end
117
+ end
118
+
119
+ # The connection should remain in tact
120
+ assert connections == redis.connections
121
+ end
122
+ end
123
+
124
+ test "SHUTDOWN from MULTI/EXEC" do
125
+ commands = {
126
+ :multi => lambda { "+OK\r\n" },
127
+ :shutdown => lambda { "+QUEUED\r\n" },
128
+ :exec => lambda { :exit }
129
+ }
130
+
131
+ redis_mock(commands) do
132
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
133
+
134
+ result = redis.multi do
135
+ redis.shutdown
136
+ end
137
+
138
+ assert nil == result
139
+ assert !redis.client.connected?
140
+ end
141
+ end
142
+
143
+ test "SHUTDOWN with error from MULTI/EXEC" do
144
+ connections = 0
145
+ commands = {
146
+ :select => lambda { |*_| connections += 1; "+OK\r\n" },
147
+ :connections => lambda { ":#{connections}\r\n" },
148
+ :multi => lambda { "+OK\r\n" },
149
+ :shutdown => lambda { "+QUEUED\r\n" },
150
+ :exec => lambda { "*1\r\n-ERR could not shutdown\r\n" }
151
+ }
152
+
153
+ redis_mock(commands) do
154
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
155
+
156
+ connections = redis.connections
157
+
158
+ # SHUTDOWN replies with an error: test that it gets returned
159
+ # We should test for Redis::CommandError here, but hiredis doesn't yet do
160
+ # custom error classes.
161
+ assert_raise(StandardError) do
162
+ redis.multi { redis.shutdown }
163
+ end
164
+
165
+ # The connection should remain intact
166
+ assert connections == redis.connections
167
+ end
168
+ end
169
+
170
+ test "SLAVEOF" do
171
+ redis_mock(:slaveof => lambda { |host, port| "+SLAVEOF #{host} #{port}" }) do
172
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
173
+
174
+ assert "SLAVEOF localhost 6381" == redis.slaveof("localhost", 6381)
175
+ end
176
+ end
177
+
178
+ test "BGREWRITEAOF" do
179
+ redis_mock(:bgrewriteaof => lambda { "+BGREWRITEAOF" }) do
180
+ redis = Redis.new(OPTIONS.merge(:port => 6380))
181
+
182
+ assert "BGREWRITEAOF" == redis.bgrewriteaof
183
+ end
184
+ end
185
+
186
+ test "CONFIG GET" do |r|
187
+ assert r.config(:get, "*")["timeout"] != nil
188
+
189
+ config = r.config(:get, "timeout")
190
+ assert ["timeout"] == config.keys
191
+ assert config.values.compact.size > 0
192
+ end
193
+
194
+ test "CONFIG SET" do |r|
195
+ begin
196
+ assert "OK" == r.config(:set, "timeout", 200)
197
+ assert "200" == r.config(:get, "*")["timeout"]
198
+
199
+ assert "OK" == r.config(:set, "timeout", 100)
200
+ assert "100" == r.config(:get, "*")["timeout"]
201
+ ensure
202
+ r.config :set, "timeout", 300
203
+ end
204
+ end
@@ -0,0 +1 @@
1
+ redis.pid
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ test "BLPOP" do |r|
12
+ r.lpush("foo", "s1")
13
+ r.lpush("foo", "s2")
14
+
15
+ wire = Wire.new do
16
+ redis = Redis::Distributed.new(NODES)
17
+ Wire.sleep 0.3
18
+ redis.lpush("foo", "s3")
19
+ end
20
+
21
+ assert ["foo", "s2"] == r.blpop("foo", 1)
22
+ assert ["foo", "s1"] == r.blpop("foo", 1)
23
+ assert ["foo", "s3"] == r.blpop("foo", 1)
24
+
25
+ wire.join
26
+ end
27
+
28
+ test "BRPOP" do |r|
29
+ r.rpush("foo", "s1")
30
+ r.rpush("foo", "s2")
31
+
32
+ wire = Wire.new do
33
+ redis = Redis::Distributed.new(NODES)
34
+ Wire.sleep 0.3
35
+ redis.rpush("foo", "s3")
36
+ end
37
+
38
+ assert ["foo", "s2"] == r.brpop("foo", 1)
39
+ assert ["foo", "s1"] == r.brpop("foo", 1)
40
+ assert ["foo", "s3"] == r.brpop("foo", 1)
41
+
42
+ wire.join
43
+ end
44
+
45
+ test "BRPOP should unset a configured socket timeout" do |r|
46
+ r = Redis::Distributed.new(NODES, :timeout => 1)
47
+
48
+ assert_nothing_raised do
49
+ r.brpop("foo", 2)
50
+ end # Errno::EAGAIN raised if socket times out before redis command times out
51
+
52
+ assert r.nodes.all? { |node| node.client.timeout == 1 }
53
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ load './test/lint/hashes.rb'
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ load './test/lint/lists.rb'
12
+
13
+ test "RPOPLPUSH" do |r|
14
+ assert_raise Redis::Distributed::CannotDistribute do
15
+ r.rpoplpush("foo", "bar")
16
+ end
17
+ end
18
+
19
+ test "BRPOPLPUSH" do |r|
20
+ assert_raise Redis::Distributed::CannotDistribute do
21
+ r.brpoplpush("foo", "bar", 1)
22
+ end
23
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ load './test/lint/sets.rb'
12
+
13
+ test "SMOVE" do |r|
14
+ assert_raise Redis::Distributed::CannotDistribute do
15
+ r.sadd "foo", "s1"
16
+ r.sadd "bar", "s2"
17
+
18
+ r.smove("foo", "bar", "s1")
19
+ end
20
+ end
21
+
22
+ test "SINTER" do |r|
23
+ assert_raise Redis::Distributed::CannotDistribute do
24
+ r.sadd "foo", "s1"
25
+ r.sadd "foo", "s2"
26
+ r.sadd "bar", "s2"
27
+
28
+ r.sinter("foo", "bar")
29
+ end
30
+ end
31
+
32
+ test "SINTERSTORE" do |r|
33
+ assert_raise Redis::Distributed::CannotDistribute do
34
+ r.sadd "foo", "s1"
35
+ r.sadd "foo", "s2"
36
+ r.sadd "bar", "s2"
37
+
38
+ r.sinterstore("baz", "foo", "bar")
39
+ end
40
+ end
41
+
42
+ test "SUNION" do |r|
43
+ assert_raise Redis::Distributed::CannotDistribute do
44
+ r.sadd "foo", "s1"
45
+ r.sadd "foo", "s2"
46
+ r.sadd "bar", "s2"
47
+ r.sadd "bar", "s3"
48
+
49
+ r.sunion("foo", "bar")
50
+ end
51
+ end
52
+
53
+ test "SUNIONSTORE" do |r|
54
+ assert_raise Redis::Distributed::CannotDistribute do
55
+ r.sadd "foo", "s1"
56
+ r.sadd "foo", "s2"
57
+ r.sadd "bar", "s2"
58
+ r.sadd "bar", "s3"
59
+
60
+ r.sunionstore("baz", "foo", "bar")
61
+ end
62
+ end
63
+
64
+ test "SDIFF" do |r|
65
+ assert_raise Redis::Distributed::CannotDistribute do
66
+ r.sadd "foo", "s1"
67
+ r.sadd "foo", "s2"
68
+ r.sadd "bar", "s2"
69
+ r.sadd "bar", "s3"
70
+
71
+ r.sdiff("foo", "bar")
72
+ end
73
+ end
74
+
75
+ test "SDIFFSTORE" do |r|
76
+ assert_raise Redis::Distributed::CannotDistribute do
77
+ r.sadd "foo", "s1"
78
+ r.sadd "foo", "s2"
79
+ r.sadd "bar", "s2"
80
+ r.sadd "bar", "s3"
81
+
82
+ r.sdiffstore("baz", "foo", "bar")
83
+ end
84
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ load './test/lint/sorted_sets.rb'
12
+
13
+ test "ZCOUNT" do |r|
14
+ r.zadd "foo", 1, "s1"
15
+ r.zadd "foo", 2, "s2"
16
+ r.zadd "foo", 3, "s3"
17
+
18
+ assert 2 == r.zcount("foo", 2, 3)
19
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+ require "redis/distributed"
5
+
6
+ setup do
7
+ log = StringIO.new
8
+ init Redis::Distributed.new(NODES, :logger => ::Logger.new(log))
9
+ end
10
+
11
+ load './test/lint/strings.rb'
12
+
13
+ test "MGET" do |r|
14
+ assert_raise Redis::Distributed::CannotDistribute do
15
+ r.mget("foo", "bar")
16
+ end
17
+ end
18
+
19
+ test "MGET mapped" do |r|
20
+ assert_raise Redis::Distributed::CannotDistribute do
21
+ r.mapped_mget("foo", "bar")
22
+ end
23
+ end
24
+
25
+ test "MSET" do |r|
26
+ assert_raise Redis::Distributed::CannotDistribute do
27
+ r.mset(:foo, "s1", :bar, "s2")
28
+ end
29
+ end
30
+
31
+ test "MSET mapped" do |r|
32
+ assert_raise Redis::Distributed::CannotDistribute do
33
+ r.mapped_mset(:foo => "s1", :bar => "s2")
34
+ end
35
+ end
36
+
37
+ test "MSETNX" do |r|
38
+ assert_raise Redis::Distributed::CannotDistribute do
39
+ r.set("foo", "s1")
40
+ r.msetnx(:foo, "s2", :bar, "s3")
41
+ end
42
+ end
43
+
44
+ test "MSETNX mapped" do |r|
45
+ assert_raise Redis::Distributed::CannotDistribute do
46
+ r.set("foo", "s1")
47
+ r.mapped_msetnx(:foo => "s2", :bar => "s3")
48
+ end
49
+ end