redis-store-pika 1.9.2.1

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.
@@ -0,0 +1,85 @@
1
+ require 'redis'
2
+ require 'redis/store/factory'
3
+ require 'redis/distributed_store'
4
+ require 'redis/store/namespace'
5
+ require 'redis/store/serialization'
6
+ require 'redis/store/version'
7
+ require 'redis/store/redis_version'
8
+ require 'redis/store/ttl'
9
+ require 'redis/store/interface'
10
+ require 'redis/store/redis_version'
11
+
12
+ class Redis
13
+ class Store < self
14
+ include Ttl, Interface, RedisVersion
15
+
16
+ def initialize(options = {})
17
+ orig_options = options.dup
18
+
19
+ _remove_unsupported_options(options)
20
+ # The options here is updated
21
+ super(options)
22
+
23
+ unless orig_options[:marshalling].nil?
24
+ puts %(
25
+ DEPRECATED: You are passing the :marshalling option, which has been
26
+ replaced with `serializer: Marshal` to support pluggable serialization
27
+ backends. To disable serialization (much like disabling marshalling),
28
+ pass `serializer: nil` in your configuration.
29
+
30
+ The :marshalling option will be removed for redis-store 2.0.
31
+ )
32
+ end
33
+
34
+ @serializer = orig_options.key?(:serializer) ? orig_options.delete(:serializer) : Marshal
35
+
36
+ unless orig_options[:marshalling].nil?
37
+ # `marshalling` only used here, might not be supported in `super`
38
+ @serializer = orig_options.delete(:marshalling) ? Marshal : nil
39
+ end
40
+
41
+ _extend_marshalling
42
+ _extend_namespace orig_options
43
+ end
44
+
45
+ def reconnect
46
+ @client.reconnect
47
+ end
48
+
49
+ def to_s
50
+ "Redis Client connected to #{location} against DB #{@client.db}"
51
+ end
52
+
53
+ def location
54
+ if @client.path
55
+ @client.path
56
+ else
57
+ h = @client.host
58
+ h = "[#{h}]" if h.include?(":")
59
+ "#{h}:#{@client.port}"
60
+ end
61
+ end
62
+
63
+ private
64
+ def _remove_unsupported_options(options)
65
+ return unless self.class.redis_client_defined?
66
+
67
+ # Unsupported keywords should be removed to avoid errors
68
+ # https://github.com/redis-rb/redis-client/blob/v0.13.0/lib/redis_client/config.rb#L21
69
+ options.delete(:raw)
70
+ options.delete(:serializer)
71
+ options.delete(:marshalling)
72
+ options.delete(:namespace)
73
+ options.delete(:scheme)
74
+ end
75
+
76
+ def _extend_marshalling
77
+ extend Serialization unless @serializer.nil?
78
+ end
79
+
80
+ def _extend_namespace(options)
81
+ @namespace = options[:namespace]
82
+ extend Namespace
83
+ end
84
+ end
85
+ end
@@ -0,0 +1 @@
1
+ require 'redis-store'
@@ -0,0 +1 @@
1
+ require 'redis/store'
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path('../lib', __FILE__)
4
+ require 'redis/store/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'redis-store-pika'
8
+ s.version = Redis::Store::VERSION
9
+ s.authors = ['Luca Guidi']
10
+ s.email = ['me@lucaguidi.com']
11
+ s.homepage = 'https://github.com/PikachuEXE/redis-store'
12
+ s.summary = 'Redis stores for Ruby frameworks'
13
+ s.description = 'Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks.'
14
+ s.post_install_message = "
15
+ This is a fork of official redis-store gem published to let people use fixes unavailable on official one yet.
16
+ Be sure to check updates from official redis-store gem sometimes in case the fixes here are merged there.
17
+ "
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.require_paths = ["lib"]
21
+ s.license = 'MIT'
22
+
23
+ s.add_dependency 'redis', '>= 4', '< 6'
24
+
25
+ s.add_development_dependency 'rake', '>= 12.3.3'
26
+ s.add_development_dependency 'bundler'
27
+ s.add_development_dependency 'mocha', '~> 2.1.0'
28
+ s.add_development_dependency 'minitest', '~> 5'
29
+ s.add_development_dependency 'git', '~> 1.2'
30
+ s.add_development_dependency 'pry-nav', '~> 0.2.4'
31
+ s.add_development_dependency 'pry', '~> 0.10.4'
32
+ s.add_development_dependency 'redis-store-testing'
33
+ s.add_development_dependency 'appraisal', '~> 2.0'
34
+ s.add_development_dependency 'rubocop', '~> 0.54'
35
+ end
@@ -0,0 +1,111 @@
1
+ require 'test_helper'
2
+
3
+ describe "Redis::DistributedStore" do
4
+ def setup
5
+ @dmr = Redis::DistributedStore.new [
6
+ { :host => "localhost", :port => "6380", :db => 0 },
7
+ { :host => "localhost", :port => "6381", :db => 0 }
8
+ ]
9
+ @rabbit = OpenStruct.new :name => "bunny"
10
+ @white_rabbit = OpenStruct.new :color => "white"
11
+ @dmr.set "rabbit", @rabbit
12
+ end
13
+
14
+ def teardown
15
+ @dmr.ring.nodes.each { |server| server.flushdb }
16
+ end
17
+
18
+ it "accepts connection params" do
19
+ dmr = Redis::DistributedStore.new [ :host => "localhost", :port => "6380", :db => "1" ]
20
+ _(dmr.ring.nodes.size).must_equal(1)
21
+ mr = dmr.ring.nodes.first
22
+ _(mr.to_s).must_equal("Redis Client connected to localhost:6380 against DB 1")
23
+ end
24
+
25
+ it "forces reconnection" do
26
+ @dmr.nodes.each do |node|
27
+ node.expects(:reconnect)
28
+ end
29
+
30
+ @dmr.reconnect
31
+ end
32
+
33
+ it "sets an object" do
34
+ @dmr.set "rabbit", @white_rabbit
35
+ _(@dmr.get("rabbit")).must_equal(@white_rabbit)
36
+ end
37
+
38
+ it "gets an object" do
39
+ _(@dmr.get("rabbit")).must_equal(@rabbit)
40
+ end
41
+
42
+ it "mget" do
43
+ @dmr.set "rabbit2", @white_rabbit
44
+ begin
45
+ @dmr.mget "rabbit", "rabbit2" do |rabbits|
46
+ rabbit, rabbit2 = rabbits
47
+ _(rabbits.length).must_equal(2)
48
+ _(rabbit).must_equal(@rabbit)
49
+ _(rabbit2).must_equal(@white_rabbit)
50
+ end
51
+ rescue Redis::Distributed::CannotDistribute
52
+ # Not supported on redis-rb < 4, and hence Ruby < 2.2.
53
+ end
54
+ end
55
+
56
+ it "mapped_mget" do
57
+ @dmr.set "rabbit2", @white_rabbit
58
+ begin
59
+ result = @dmr.mapped_mget("rabbit", "rabbit2")
60
+ _(result.keys).must_equal %w[ rabbit rabbit2 ]
61
+ _(result["rabbit"]).must_equal @rabbit
62
+ _(result["rabbit2"]).must_equal @white_rabbit
63
+ rescue Redis::Distributed::CannotDistribute
64
+ # Not supported on redis-rb < 4, and hence Ruby < 2.2.
65
+ end
66
+ end
67
+
68
+ it "passes through ring replica options" do
69
+ dmr = Redis::DistributedStore.new [
70
+ { :host => "localhost", :port => "6380", :db => 0 },
71
+ { :host => "localhost", :port => "6381", :db => 0 }
72
+ ], replicas: 1024
73
+ _(dmr.ring.replicas).must_equal 1024
74
+ end
75
+
76
+ it "uses a custom ring object" do
77
+ my_ring = Redis::HashRing.new
78
+ dmr = Redis::DistributedStore.new [
79
+ { :host => "localhost", :port => "6380", :db => 0 },
80
+ { :host => "localhost", :port => "6381", :db => 0 }
81
+ ], ring: my_ring
82
+ _(dmr.ring).must_equal my_ring
83
+ _(dmr.ring.nodes.length).must_equal 2
84
+ end
85
+
86
+ describe '#redis_version' do
87
+ it 'returns redis version' do
88
+ @dmr.nodes.first.expects(:redis_version)
89
+ @dmr.redis_version
90
+ end
91
+ end
92
+
93
+ describe '#supports_redis_version?' do
94
+ it 'returns redis version' do
95
+ @dmr.nodes.first.expects(:supports_redis_version?).with('2.8.0')
96
+ @dmr.supports_redis_version?('2.8.0')
97
+ end
98
+ end
99
+
100
+ describe "namespace" do
101
+ it "uses namespaced key" do
102
+ @dmr = Redis::DistributedStore.new [
103
+ { :host => "localhost", :port => "6380", :db => 0 },
104
+ { :host => "localhost", :port => "6381", :db => 0 }
105
+ ], :namespace => "theplaylist"
106
+
107
+ @dmr.expects(:node_for).with("theplaylist:rabbit").returns(@dmr.nodes.first)
108
+ @dmr.get "rabbit"
109
+ end
110
+ end
111
+ end unless ENV['CI']
@@ -0,0 +1,273 @@
1
+ require 'test_helper'
2
+ require 'json'
3
+
4
+ describe "Redis::Store::Factory" do
5
+ describe ".create" do
6
+ describe "when not given any arguments" do
7
+ it "instantiates Redis::Store" do
8
+ store = Redis::Store::Factory.create
9
+ _(store).must_be_kind_of(Redis::Store)
10
+ # `redis.rb` use different default host values in v4 & v5
11
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0$})
12
+ end
13
+ end
14
+
15
+ describe "when given a Hash" do
16
+ it "uses specified host" do
17
+ store = Redis::Store::Factory.create :host => "localhost"
18
+ _(store.to_s).must_equal("Redis Client connected to localhost:6379 against DB 0")
19
+ end
20
+
21
+ it "uses specified port" do
22
+ store = Redis::Store::Factory.create :host => "localhost", :port => 6380
23
+ _(store.to_s).must_equal("Redis Client connected to localhost:6380 against DB 0")
24
+ end
25
+
26
+ it "uses specified scheme" do
27
+ store = Redis::Store::Factory.create :scheme => "rediss"
28
+ client = store.instance_variable_get(:@client)
29
+ # `redis-client` does NOT have `scheme`
30
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('rediss')
31
+ end
32
+
33
+ it "uses specified path" do
34
+ store = Redis::Store::Factory.create :path => "/var/run/redis.sock"
35
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
36
+ end
37
+
38
+ it "uses specified db" do
39
+ store = Redis::Store::Factory.create :host => "localhost", :port => 6380, :db => 13
40
+ _(store.to_s).must_equal("Redis Client connected to localhost:6380 against DB 13")
41
+ end
42
+
43
+ it "uses specified namespace" do
44
+ store = Redis::Store::Factory.create :namespace => "theplaylist"
45
+ # `redis.rb` use different default host values in v4 & v5
46
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0 with namespace theplaylist$})
47
+ end
48
+
49
+ it "uses specified key_prefix as namespace" do
50
+ store = Redis::Store::Factory.create :key_prefix => "theplaylist"
51
+ # `redis.rb` use different default host values in v4 & v5
52
+ _(store.to_s).must_match(%r{^Redis Client connected to (127.0.0.1|localhost):6379 against DB 0 with namespace theplaylist$})
53
+ end
54
+
55
+ it "uses specified password" do
56
+ store = Redis::Store::Factory.create :password => "secret"
57
+ _(store.instance_variable_get(:@client).password).must_equal("secret")
58
+ end
59
+
60
+ it 'uses empty password' do
61
+ store = Redis::Store::Factory.create :password => ''
62
+ _(store.instance_variable_get(:@client).password).must_equal('')
63
+ end
64
+
65
+ it 'uses nil password' do
66
+ store = Redis::Store::Factory.create :password => nil
67
+ assert_nil(store.instance_variable_get(:@client).password)
68
+ end
69
+
70
+ it "disables serialization" do
71
+ store = Redis::Store::Factory.create :serializer => nil
72
+ _(store.instance_variable_get(:@serializer)).must_be_nil
73
+ # `raw` would be removed when `redis-client` is used
74
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(true)
75
+ end
76
+
77
+ it "configures pluggable serialization backend" do
78
+ store = Redis::Store::Factory.create :serializer => JSON
79
+ _(store.instance_variable_get(:@serializer)).must_equal(JSON)
80
+ # `raw` would be removed when `redis-client` is used
81
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(false)
82
+ end
83
+
84
+ describe "defaults" do
85
+ it "defaults to localhost if no host specified" do
86
+ store = Redis::Store::Factory.create
87
+ # `redis.rb` use different default host values in v4 & v5
88
+ _(store.instance_variable_get(:@client).host).must_match(%r{^127.0.0.1|localhost$})
89
+ end
90
+
91
+ it "defaults to 6379 if no port specified" do
92
+ store = Redis::Store::Factory.create
93
+ _(store.instance_variable_get(:@client).port).must_equal(6379)
94
+ end
95
+
96
+ it "defaults to redis:// if no scheme specified" do
97
+ store = Redis::Store::Factory.create
98
+ client = store.instance_variable_get(:@client)
99
+ # `redis-client` does NOT have `scheme`
100
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('redis')
101
+ end
102
+ end
103
+
104
+ describe 'with stdout disabled' do
105
+ before do
106
+ @original_stderr = $stderr
107
+ @original_stdout = $stdout
108
+
109
+ $stderr = Tempfile.new('stderr')
110
+ $stdout = Tempfile.new('stdout')
111
+ end
112
+
113
+ it "disables marshalling and provides deprecation warning" do
114
+ store = Redis::Store::Factory.create :marshalling => false
115
+ _(store.instance_variable_get(:@serializer)).must_be_nil
116
+ # `raw` would be removed when `redis-client` is used
117
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(true)
118
+ end
119
+
120
+ it "enables marshalling but provides warning to use :serializer instead" do
121
+ store = Redis::Store::Factory.create :marshalling => true
122
+ _(store.instance_variable_get(:@serializer)).must_equal(Marshal)
123
+ # `raw` would be removed when `redis-client` is used
124
+ defined?(::RedisClient) || _(store.instance_variable_get(:@options)[:raw]).must_equal(false)
125
+ end
126
+
127
+ after do
128
+ $stderr = @original_stderr
129
+ $stdout = @original_stdout
130
+ end
131
+ end
132
+
133
+ it "should instantiate a Redis::DistributedStore store" do
134
+ store = Redis::Store::Factory.create(
135
+ { :host => "localhost", :port => 6379 },
136
+ { :host => "localhost", :port => 6380 }
137
+ )
138
+ _(store).must_be_kind_of(Redis::DistributedStore)
139
+ _(store.nodes.map { |node| node.to_s }).must_equal([
140
+ "Redis Client connected to localhost:6379 against DB 0",
141
+ "Redis Client connected to localhost:6380 against DB 0",
142
+ ])
143
+ end
144
+ end
145
+
146
+ describe "when given a String" do
147
+ it "uses specified host" do
148
+ store = Redis::Store::Factory.create "redis://127.0.0.1"
149
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0")
150
+ end
151
+
152
+ it "uses specified port" do
153
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6380"
154
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6380 against DB 0")
155
+ end
156
+
157
+ it "uses specified scheme" do
158
+ store = Redis::Store::Factory.create "rediss://127.0.0.1:6380"
159
+ client = store.instance_variable_get(:@client)
160
+ # `redis-client` does NOT have `scheme`
161
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('rediss')
162
+ end
163
+
164
+ it "correctly defaults to redis:// when relative scheme specified" do
165
+ store = Redis::Store::Factory.create "//127.0.0.1:6379"
166
+ client = store.instance_variable_get(:@client)
167
+ # `redis-client` does NOT have `scheme`
168
+ client.respond_to?(:scheme) && _(client.scheme).must_equal('redis')
169
+ end
170
+
171
+ it "uses specified path" do
172
+ store = Redis::Store::Factory.create "unix:///var/run/redis.sock"
173
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 0")
174
+ end
175
+
176
+ it "uses specified db" do
177
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6380/13"
178
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6380 against DB 13")
179
+ end
180
+
181
+ it "uses specified namespace" do
182
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
183
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
184
+ end
185
+
186
+ it "uses specified via query namespace" do
187
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0?namespace=theplaylist"
188
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
189
+ end
190
+
191
+ it "uses specified namespace with path" do
192
+ store = Redis::Store::Factory.create "unix:///var/run/redis.sock?db=2&namespace=theplaylist"
193
+ _(store.to_s).must_equal("Redis Client connected to /var/run/redis.sock against DB 2 with namespace theplaylist")
194
+ end
195
+
196
+ it "uses specified password" do
197
+ store = Redis::Store::Factory.create "redis://:secret@127.0.0.1:6379/0/theplaylist"
198
+ _(store.instance_variable_get(:@client).password).must_equal("secret")
199
+ end
200
+
201
+ it 'uses specified password with special characters' do
202
+ store = Redis::Store::Factory.create 'redis://:pwd%40123@127.0.0.1:6379/0/theplaylist'
203
+ _(store.instance_variable_get(:@client).password).must_equal('pwd@123')
204
+ end
205
+
206
+ it 'uses empty password' do
207
+ store = Redis::Store::Factory.create 'redis://:@127.0.0.1:6379/0/theplaylist'
208
+ _(store.instance_variable_get(:@client).password).must_equal('')
209
+ end
210
+
211
+ it 'uses nil password' do
212
+ store = Redis::Store::Factory.create 'redis://127.0.0.1:6379/0/theplaylist'
213
+ assert_nil(store.instance_variable_get(:@client).password)
214
+ end
215
+
216
+ it "correctly uses specified ipv6 host" do
217
+ store = Redis::Store::Factory.create "redis://[::1]:6380"
218
+ _(store.to_s).must_equal("Redis Client connected to [::1]:6380 against DB 0")
219
+ _(store.instance_variable_get('@options')[:host]).must_equal("::1")
220
+ end
221
+
222
+ it "instantiates Redis::DistributedStore" do
223
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380"
224
+ _(store).must_be_kind_of(Redis::DistributedStore)
225
+ _(store.nodes.map { |node| node.to_s }).must_equal([
226
+ "Redis Client connected to 127.0.0.1:6379 against DB 0",
227
+ "Redis Client connected to 127.0.0.1:6380 against DB 0",
228
+ ])
229
+ end
230
+ end
231
+
232
+ describe 'when given host Hash and options Hash' do
233
+ it 'instantiates Redis::Store and merges options' do
234
+ Redis::Store::Factory.create(
235
+ { :host => '127.0.0.1', :port => '6379' },
236
+ { :namespace => 'theplaylist' }
237
+ )
238
+ end
239
+
240
+ it 'instantiates Redis::DistributedStore and merges options' do
241
+ store = Redis::Store::Factory.create(
242
+ { :host => '127.0.0.1', :port => '6379' },
243
+ { :host => '127.0.0.1', :port => '6380' },
244
+ { :namespace => 'theplaylist' }
245
+ )
246
+ _(store.nodes.map { |node| node.to_s }).must_equal([
247
+ "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
248
+ "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist"
249
+ ])
250
+ end
251
+ end
252
+
253
+ describe 'when given host String and options Hash' do
254
+ it 'instantiates Redis::Store and merges options' do
255
+ store = Redis::Store::Factory.create "redis://127.0.0.1", :namespace => 'theplaylist'
256
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
257
+ end
258
+
259
+ it 'instantiates Redis::DistributedStore and merges options' do
260
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380", :namespace => 'theplaylist'
261
+ _(store.nodes.map { |node| node.to_s }).must_equal([
262
+ "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist",
263
+ "Redis Client connected to 127.0.0.1:6380 against DB 0 with namespace theplaylist",
264
+ ])
265
+ end
266
+
267
+ it 'instantiates Redis::Store and sets namespace from String' do
268
+ store = Redis::Store::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
269
+ _(store.to_s).must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class InterfacedRedis < Redis
4
+ include Redis::Store::Interface
5
+ end
6
+
7
+ describe Redis::Store::Interface do
8
+ before do
9
+ @r = InterfacedRedis.new
10
+ end
11
+
12
+ it "should get an element" do
13
+ lambda { @r.get("key", :option => true) } # .wont_raise ArgumentError
14
+ end
15
+
16
+ it "should set an element" do
17
+ lambda { @r.set("key", "value", :option => true) } # .wont_raise ArgumentError
18
+ end
19
+
20
+ it "should setnx an element" do
21
+ lambda { @r.setnx("key", "value", :option => true) } # .wont_raise ArgumentError
22
+ end
23
+
24
+ it "should setex an element" do
25
+ lambda { @r.setex("key", 1, "value", :option => true) } # .wont_raise ArgumentError
26
+ end
27
+ end