fault_tolerant_redis-activesupport 4.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9c294041252356e5f9da6aaae0afb056b72f9853
4
+ data.tar.gz: 5ebe62c437f156ec1e8bfa072546fca3784fda20
5
+ SHA512:
6
+ metadata.gz: 7e5d1629b9f420cedcd595c1dfaf7e17170636c678983029c839e8dd03ea8f0bf61be73d0313502f873f1e5d09c222782330be03dd96cdc848650a81b47b3153
7
+ data.tar.gz: dc0042f8adb6655ac7d2b90d293ab41589c5ab323f84ada2f07e9e0d051b5995aabf8684a3756c8c9756cda5ed6af4168a09da9788b94d386ff37211aa658ace
data/.env ADDED
@@ -0,0 +1,19 @@
1
+ local ruby_version_path='.ruby-version'
2
+ local ruby_gemset_path='.ruby-gemset'
3
+
4
+ if [[ -f $ruby_version_path ]]; then
5
+ local ruby_version=`cat $ruby_version_path`
6
+ fi
7
+
8
+ if [[ -f $ruby_gemset_path ]]; then
9
+ local ruby_gemset=`cat $ruby_gemset_path`
10
+ fi
11
+
12
+ if [ ! -z $ruby_version ]; then
13
+ if [ ! -z $ruby_gemset ]; then
14
+ echo `which rvm`
15
+ rvm use $ruby_version@$ruby_gemset
16
+ else
17
+ rvm use $ruby_version
18
+ fi
19
+ fi
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ tmp/
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ script: 'bundle exec rake'
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - ruby-head
7
+ - rbx-19mode
8
+ - jruby-19mode
9
+ - jruby-head
10
+
11
+ matrix:
12
+ allow_failures:
13
+ - rvm: jruby-head
14
+ - rvm: ruby-head
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+ ruby File.read(".ruby-version").strip
3
+ gemspec
4
+
5
+ if ::File.directory?(gem_path = '../redis-store')
6
+ gem 'redis-store', '~> 1.1.0', path: gem_path
7
+ end
8
+
9
+ gem 'i18n'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 - 2011 Luca Guidi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Redis stores for ActiveSupport
2
+
3
+ __`redis-activesupport`__ provides a cache for __ActiveSupport__. See the main [redis-store readme](https://github.com/redis-store/redis-store) for general guidelines.
4
+
5
+ ## Installation
6
+
7
+ ```ruby
8
+ # Gemfile
9
+ gem 'redis-activesupport'
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ If you are using redis-store with Rails, consider using the [redis-rails gem](https://github.com/redis-store/redis-rails) instead. For standalone usage:
15
+
16
+ ```ruby
17
+ ActiveSupport::Cache.lookup_store :redis_store # { ... optional configuration ... }
18
+ ```
19
+
20
+ ## Running tests
21
+
22
+ ```shell
23
+ gem install bundler
24
+ git clone git://github.com/redis-store/redis-activesupport.git
25
+ cd redis-activesupport
26
+ bundle install
27
+ bundle exec rake
28
+ ```
29
+
30
+ If you are on **Snow Leopard** you have to run `env ARCHFLAGS="-arch x86_64" bundle exec rake`
31
+
32
+ ## Status
33
+
34
+ [![Gem Version](https://badge.fury.io/rb/redis-activesupport.png)](http://badge.fury.io/rb/redis-activesupport) [![Build Status](https://secure.travis-ci.org/redis-store/redis-activesupport.png?branch=master)](http://travis-ci.org/jodosha/redis-activesupport?branch=master) [![Code Climate](https://codeclimate.com/github/jodosha/redis-store.png)](https://codeclimate.com/github/redis-store/redis-activesupport)
35
+
36
+ ## Copyright
37
+
38
+ 2009 - 2013 Luca Guidi - [http://lucaguidi.com](http://lucaguidi.com), released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/setup'
2
+ require 'rake'
3
+ require 'bundler/gem_tasks'
4
+ require 'redis-store/testing/tasks'
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'redis/activesupport/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'fault_tolerant_redis-activesupport'
7
+ s.version = Redis::ActiveSupport::VERSION
8
+ s.authors = ['Luca Guidi', 'Jan Renra Gloser']
9
+ s.email = ['me@lucaguidi.com', 'jan.renra.gloser@gmail.com']
10
+ s.homepage = 'https://github.com/renra/redis-activesupport'
11
+ s.summary = %q{Fault tolerant redis store for ActiveSupport}
12
+ s.description = %q{Fault tolerant redis store for ActiveSupport}
13
+ s.license = 'MIT'
14
+
15
+ s.rubyforge_project = 'redis-activesupport'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ['lib']
21
+
22
+ s.add_runtime_dependency 'redis-store', '~> 1.1.0'
23
+ s.add_runtime_dependency 'activesupport', '~> 4'
24
+ s.add_runtime_dependency 'maybe_client', '1.1.0'
25
+
26
+ s.add_development_dependency 'rake', '~> 10'
27
+ s.add_development_dependency 'bundler', '~> 1.3'
28
+ s.add_development_dependency 'mocha', '~> 0.14.0'
29
+ s.add_development_dependency 'minitest', '~> 4.2'
30
+ s.add_development_dependency 'redis-store-testing'
31
+ end
32
+
@@ -0,0 +1,207 @@
1
+ # encoding: UTF-8
2
+ require 'redis-store'
3
+ require 'maybe_client'
4
+
5
+ module ActiveSupport
6
+ module Cache
7
+ class FaultTolerantRedisStore < Store
8
+ # Instantiate the store.
9
+ #
10
+ # Example:
11
+ # RedisStore.new
12
+ # # => host: localhost, port: 6379, db: 0
13
+ #
14
+ # RedisStore.new "example.com"
15
+ # # => host: example.com, port: 6379, db: 0
16
+ #
17
+ # RedisStore.new "example.com:23682"
18
+ # # => host: example.com, port: 23682, db: 0
19
+ #
20
+ # RedisStore.new "example.com:23682/1"
21
+ # # => host: example.com, port: 23682, db: 1
22
+ #
23
+ # RedisStore.new "example.com:23682/1/theplaylist"
24
+ # # => host: example.com, port: 23682, db: 1, namespace: theplaylist
25
+ #
26
+ # RedisStore.new "localhost:6379/0", "localhost:6380/0"
27
+ # # => instantiate a cluster
28
+ def initialize(*addresses)
29
+ @data = MaybeClient.new(client: ::Redis::Store::Factory.create(addresses))
30
+ super(addresses.extract_options!)
31
+ end
32
+
33
+ def write(name, value, options = nil)
34
+ options = merged_options(options)
35
+ instrument(:write, name, options) do |payload|
36
+ entry = options[:raw].present? ? value : Entry.new(value, options)
37
+ write_entry(namespaced_key(name, options), entry, options)
38
+ end
39
+ end
40
+
41
+ # Delete objects for matched keys.
42
+ #
43
+ # Performance note: this operation can be dangerous for large production
44
+ # databases, as it uses the Redis "KEYS" command, which is O(N) over the
45
+ # total number of keys in the database. Users of large Redis caches should
46
+ # avoid this method.
47
+ #
48
+ # Example:
49
+ # cache.del_matched "rab*"
50
+ def delete_matched(matcher, options = nil)
51
+ options = merged_options(options)
52
+ instrument(:delete_matched, matcher.inspect) do
53
+ matcher = key_matcher(matcher, options)
54
+ begin
55
+ !(keys = @data.keys(matcher)).empty? && @data.del(*keys)
56
+ rescue Errno::ECONNREFUSED => e
57
+ false
58
+ end
59
+ end
60
+ end
61
+
62
+ # Reads multiple keys from the cache using a single call to the
63
+ # servers for all keys. Options can be passed in the last argument.
64
+ #
65
+ # Example:
66
+ # cache.read_multi "rabbit", "white-rabbit"
67
+ # cache.read_multi "rabbit", "white-rabbit", :raw => true
68
+ def read_multi(*names)
69
+ values = @data.mget(*names)
70
+ values.map! { |v| v.is_a?(ActiveSupport::Cache::Entry) ? v.value : v }
71
+
72
+ # Remove the options hash before mapping keys to values
73
+ names.extract_options!
74
+
75
+ result = Hash[names.zip(values)]
76
+ result.reject!{ |k,v| v.nil? }
77
+ result
78
+ end
79
+
80
+ # Increment a key in the store.
81
+ #
82
+ # If the key doesn't exist it will be initialized on 0.
83
+ # If the key exist but it isn't a Fixnum it will be initialized on 0.
84
+ #
85
+ # Example:
86
+ # We have two objects in cache:
87
+ # counter # => 23
88
+ # rabbit # => #<Rabbit:0x5eee6c>
89
+ #
90
+ # cache.increment "counter"
91
+ # cache.read "counter", :raw => true # => "24"
92
+ #
93
+ # cache.increment "counter", 6
94
+ # cache.read "counter", :raw => true # => "30"
95
+ #
96
+ # cache.increment "a counter"
97
+ # cache.read "a counter", :raw => true # => "1"
98
+ #
99
+ # cache.increment "rabbit"
100
+ # cache.read "rabbit", :raw => true # => "1"
101
+ def increment(key, amount = 1)
102
+ instrument(:increment, key, :amount => amount) do
103
+ @data.incrby key, amount
104
+ end
105
+ end
106
+
107
+ # Decrement a key in the store
108
+ #
109
+ # If the key doesn't exist it will be initialized on 0.
110
+ # If the key exist but it isn't a Fixnum it will be initialized on 0.
111
+ #
112
+ # Example:
113
+ # We have two objects in cache:
114
+ # counter # => 23
115
+ # rabbit # => #<Rabbit:0x5eee6c>
116
+ #
117
+ # cache.decrement "counter"
118
+ # cache.read "counter", :raw => true # => "22"
119
+ #
120
+ # cache.decrement "counter", 2
121
+ # cache.read "counter", :raw => true # => "20"
122
+ #
123
+ # cache.decrement "a counter"
124
+ # cache.read "a counter", :raw => true # => "-1"
125
+ #
126
+ # cache.decrement "rabbit"
127
+ # cache.read "rabbit", :raw => true # => "-1"
128
+ def decrement(key, amount = 1)
129
+ instrument(:decrement, key, :amount => amount) do
130
+ @data.decrby key, amount
131
+ end
132
+ end
133
+
134
+ def expire(key, ttl)
135
+ @data.expire key, ttl
136
+ end
137
+
138
+ # Clear all the data from the store.
139
+ def clear
140
+ instrument(:clear, nil, nil) do
141
+ @data.flushdb
142
+ end
143
+ end
144
+
145
+ # fixed problem with invalid exists? method
146
+ # https://github.com/rails/rails/commit/cad2c8f5791d5bd4af0f240d96e00bae76eabd2f
147
+ def exist?(name, options = nil)
148
+ res = super(name, options)
149
+ res || false
150
+ end
151
+
152
+ def stats
153
+ @data.info
154
+ end
155
+
156
+ # Force client reconnection, useful Unicorn deployed apps.
157
+ def reconnect
158
+ @data.reconnect
159
+ end
160
+
161
+ protected
162
+ def write_entry(key, entry, options)
163
+ method = options && options[:unless_exist] ? :setnx : :set
164
+ @data.send method, key, entry, options
165
+ rescue Errno::ECONNREFUSED => e
166
+ false
167
+ end
168
+
169
+ def read_entry(key, options)
170
+ entry = @data.get key, options
171
+ if entry
172
+ entry.is_a?(ActiveSupport::Cache::Entry) ? entry : ActiveSupport::Cache::Entry.new(entry)
173
+ end
174
+ rescue Errno::ECONNREFUSED => e
175
+ nil
176
+ end
177
+
178
+ ##
179
+ # Implement the ActiveSupport::Cache#delete_entry
180
+ #
181
+ # It's really needed and use
182
+ #
183
+ def delete_entry(key, options)
184
+ @data.del key
185
+ rescue Errno::ECONNREFUSED => e
186
+ false
187
+ end
188
+
189
+
190
+ # Add the namespace defined in the options to a pattern designed to match keys.
191
+ #
192
+ # This implementation is __different__ than ActiveSupport:
193
+ # __it doesn't accept Regular expressions__, because the Redis matcher is designed
194
+ # only for strings with wildcards.
195
+ def key_matcher(pattern, options)
196
+ prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
197
+ if prefix
198
+ raise "Regexps aren't supported, please use string with wildcards." if pattern.is_a?(Regexp)
199
+ "#{prefix}:#{pattern}"
200
+ else
201
+ pattern
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+
@@ -0,0 +1,4 @@
1
+ require 'redis-store'
2
+ require 'active_support'
3
+ require 'redis/activesupport/version'
4
+ require 'active_support/cache/fault_tolerant_redis_store'
@@ -0,0 +1,5 @@
1
+ class Redis
2
+ module ActiveSupport
3
+ VERSION = '4.0.0'
4
+ end
5
+ end
@@ -0,0 +1,320 @@
1
+ require 'test_helper'
2
+
3
+ describe ActiveSupport::Cache::RedisStore do
4
+ def setup
5
+ @store = ActiveSupport::Cache::RedisStore.new
6
+ @dstore = ActiveSupport::Cache::RedisStore.new "redis://127.0.0.1:6380/1", "redis://127.0.0.1:6381/1"
7
+ @rabbit = OpenStruct.new :name => "bunny"
8
+ @white_rabbit = OpenStruct.new :color => "white"
9
+
10
+ with_store_management do |store|
11
+ store.write "rabbit", @rabbit
12
+ store.delete "counter"
13
+ store.delete "rub-a-dub"
14
+ end
15
+ end
16
+
17
+ it "reads the data" do
18
+ with_store_management do |store|
19
+ store.read("rabbit").must_equal(@rabbit)
20
+ end
21
+ end
22
+
23
+ it "writes the data" do
24
+ with_store_management do |store|
25
+ store.write "rabbit", @white_rabbit
26
+ store.read("rabbit").must_equal(@white_rabbit)
27
+ end
28
+ end
29
+
30
+ it "writes the data with expiration time" do
31
+ with_store_management do |store|
32
+ store.write "rabbit", @white_rabbit, :expires_in => 1.second
33
+ store.read("rabbit").must_equal(@white_rabbit)
34
+ sleep 2
35
+ store.read("rabbit").must_be_nil
36
+ end
37
+ end
38
+
39
+ it "respects expiration time in seconds" do
40
+ with_store_management do |store|
41
+ store.write "rabbit", @white_rabbit
42
+ store.read("rabbit").must_equal(@white_rabbit)
43
+ store.expire "rabbit", 1.seconds
44
+ sleep 2
45
+ store.read("rabbit").must_be_nil
46
+ end
47
+ end
48
+
49
+ it "respects expiration time in minutes" do
50
+ with_store_management do |store|
51
+ store.write "rabbit", @white_rabbit
52
+ store.read("rabbit").must_equal(@white_rabbit)
53
+ store.expire "rabbit", 1.minutes
54
+ sleep 61
55
+ store.read("rabbit").must_be_nil
56
+ end
57
+ end
58
+
59
+ it "does't write data if :unless_exist option is true" do
60
+ with_store_management do |store|
61
+ store.write "rabbit", @white_rabbit, :unless_exist => true
62
+ store.read("rabbit").must_equal(@rabbit)
63
+ end
64
+ end
65
+
66
+ if RUBY_VERSION.match /1\.9/
67
+ it "reads raw data" do
68
+ with_store_management do |store|
69
+ result = store.read("rabbit", :raw => true)
70
+ result.must_include("ActiveSupport::Cache::Entry")
71
+ result.must_include("\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF")
72
+ end
73
+ end
74
+ else
75
+ it "reads raw data" do
76
+ with_store_management do |store|
77
+ result = store.read("rabbit", :raw => true)
78
+ result.must_include("ActiveSupport::Cache::Entry")
79
+ result.must_include("\017OpenStruct{\006:\tname")
80
+ end
81
+ end
82
+ end
83
+
84
+ it "writes raw data" do
85
+ with_store_management do |store|
86
+ store.write "rabbit", @white_rabbit, :raw => true
87
+ store.read("rabbit", :raw => true).must_equal(%(#<OpenStruct color=\"white\">))
88
+ end
89
+ end
90
+
91
+ it "deletes data" do
92
+ with_store_management do |store|
93
+ store.delete "rabbit"
94
+ store.read("rabbit").must_be_nil
95
+ end
96
+ end
97
+
98
+ it "deletes matched data" do
99
+ with_store_management do |store|
100
+ store.delete_matched "rabb*"
101
+ store.read("rabbit").must_be_nil
102
+ end
103
+ end
104
+
105
+ it "verifies existence of an object in the store" do
106
+ with_store_management do |store|
107
+ store.exist?("rabbit").must_equal(true)
108
+ store.exist?("rab-a-dub").must_equal(false)
109
+ end
110
+ end
111
+
112
+ it "increments a key" do
113
+ with_store_management do |store|
114
+ 3.times { store.increment "counter" }
115
+ store.read("counter", :raw => true).to_i.must_equal(3)
116
+ end
117
+ end
118
+
119
+ it "decrements a key" do
120
+ with_store_management do |store|
121
+ 3.times { store.increment "counter" }
122
+ 2.times { store.decrement "counter" }
123
+ store.read("counter", :raw => true).to_i.must_equal(1)
124
+ end
125
+ end
126
+
127
+ it "increments a raw key" do
128
+ with_store_management do |store|
129
+ assert store.write("raw-counter", 1, :raw => true)
130
+ store.increment("raw-counter", 2)
131
+ store.read("raw-counter", :raw => true).to_i.must_equal(3)
132
+ end
133
+ end
134
+
135
+ it "decrements a raw key" do
136
+ with_store_management do |store|
137
+ assert store.write("raw-counter", 3, :raw => true)
138
+ store.decrement("raw-counter", 2)
139
+ store.read("raw-counter", :raw => true).to_i.must_equal(1)
140
+ end
141
+ end
142
+
143
+ it "increments a key by given value" do
144
+ with_store_management do |store|
145
+ store.increment "counter", 3
146
+ store.read("counter", :raw => true).to_i.must_equal(3)
147
+ end
148
+ end
149
+
150
+ it "decrements a key by given value" do
151
+ with_store_management do |store|
152
+ 3.times { store.increment "counter" }
153
+ store.decrement "counter", 2
154
+ store.read("counter", :raw => true).to_i.must_equal(1)
155
+ end
156
+ end
157
+
158
+ it "clears the store" do
159
+ with_store_management do |store|
160
+ store.clear
161
+ store.instance_variable_get(:@data).keys("*").flatten.must_be_empty
162
+ end
163
+ end
164
+
165
+ it "provides store stats" do
166
+ with_store_management do |store|
167
+ store.stats.wont_be_empty
168
+ end
169
+ end
170
+
171
+ it "fetches data" do
172
+ with_store_management do |store|
173
+ store.fetch("rabbit").must_equal(@rabbit)
174
+ store.fetch("rub-a-dub").must_be_nil
175
+ store.fetch("rub-a-dub") { "Flora de Cana" }
176
+ store.fetch("rub-a-dub").must_equal("Flora de Cana")
177
+ store.fetch("rabbit", :force => true) # force cache miss
178
+ store.fetch("rabbit", :force => true, :expires_in => 1.second) { @white_rabbit }
179
+ # store.fetch("rabbit").must_equal(@white_rabbit)
180
+ sleep 2
181
+ store.fetch("rabbit").must_be_nil
182
+ end
183
+ end
184
+
185
+ it "reads multiple keys" do
186
+ @store.write "irish whisky", "Jameson"
187
+ result = @store.read_multi "rabbit", "irish whisky"
188
+ result['rabbit'].must_equal(@rabbit)
189
+ result['irish whisky'].must_equal("Jameson")
190
+ end
191
+
192
+ it "reads multiple keys and returns only the matched ones" do
193
+ @store.delete 'irish whisky'
194
+ result = @store.read_multi "rabbit", "irish whisky"
195
+ result.wont_include('irish whisky')
196
+ result.must_include('rabbit')
197
+ end
198
+
199
+ describe "notifications" do
200
+ it "notifies on #fetch" do
201
+ with_notifications do
202
+ @store.fetch("radiohead") { "House Of Cards" }
203
+ end
204
+
205
+ read, generate, write = @events
206
+
207
+ read.name.must_equal('cache_read.active_support')
208
+ read.payload.must_equal({ :key => 'radiohead', :super_operation => :fetch })
209
+
210
+ generate.name.must_equal('cache_generate.active_support')
211
+ generate.payload.must_equal({ :key => 'radiohead' })
212
+
213
+ write.name.must_equal('cache_write.active_support')
214
+ write.payload.must_equal({ :key => 'radiohead' })
215
+ end
216
+
217
+ it "notifies on #read" do
218
+ with_notifications do
219
+ @store.read "metallica"
220
+ end
221
+
222
+ read = @events.first
223
+ read.name.must_equal('cache_read.active_support')
224
+ read.payload.must_equal({ :key => 'metallica', :hit => false })
225
+ end
226
+
227
+ it "notifies on #write" do
228
+ with_notifications do
229
+ @store.write "depeche mode", "Enjoy The Silence"
230
+ end
231
+
232
+ write = @events.first
233
+ write.name.must_equal('cache_write.active_support')
234
+ write.payload.must_equal({ :key => 'depeche mode' })
235
+ end
236
+
237
+ it "notifies on #delete" do
238
+ with_notifications do
239
+ @store.delete "the new cardigans"
240
+ end
241
+
242
+ delete = @events.first
243
+ delete.name.must_equal('cache_delete.active_support')
244
+ delete.payload.must_equal({ :key => 'the new cardigans' })
245
+ end
246
+
247
+ it "notifies on #exist?" do
248
+ with_notifications do
249
+ @store.exist? "the smiths"
250
+ end
251
+
252
+ exist = @events.first
253
+ exist.name.must_equal('cache_exist?.active_support')
254
+ exist.payload.must_equal({ :key => 'the smiths' })
255
+ end
256
+
257
+ it "notifies on #delete_matched" do
258
+ with_notifications do
259
+ @store.delete_matched "afterhours*"
260
+ end
261
+
262
+ delete_matched = @events.first
263
+ delete_matched.name.must_equal('cache_delete_matched.active_support')
264
+ delete_matched.payload.must_equal({ :key => %("afterhours*") })
265
+ end
266
+
267
+ it "notifies on #increment" do
268
+ with_notifications do
269
+ @store.increment "pearl jam"
270
+ end
271
+
272
+ increment = @events.first
273
+ increment.name.must_equal('cache_increment.active_support')
274
+ increment.payload.must_equal({ :key => 'pearl jam', :amount => 1 })
275
+ end
276
+
277
+ it "notifies on #decrement" do
278
+ with_notifications do
279
+ @store.decrement "placebo"
280
+ end
281
+
282
+ decrement = @events.first
283
+ decrement.name.must_equal('cache_decrement.active_support')
284
+ decrement.payload.must_equal({ :key => 'placebo', :amount => 1 })
285
+ end
286
+
287
+ # it "notifies on cleanup" # TODO implement in ActiveSupport::Cache::RedisStore
288
+
289
+ it "should notify on clear" do
290
+ with_notifications do
291
+ @store.clear
292
+ end
293
+
294
+ clear = @events.first
295
+ clear.name.must_equal('cache_clear.active_support')
296
+ clear.payload.must_equal({ :key => nil })
297
+ end
298
+ end
299
+
300
+ private
301
+ def instantiate_store(addresses = nil)
302
+ ActiveSupport::Cache::RedisStore.new(addresses).instance_variable_get(:@data)
303
+ end
304
+
305
+ def with_store_management
306
+ yield @store
307
+ yield @dstore
308
+ end
309
+
310
+ def with_notifications
311
+ @events = [ ]
312
+ ActiveSupport::Cache::RedisStore.instrument = true
313
+ ActiveSupport::Notifications.subscribe(/^cache_(.*)\.active_support$/) do |*args|
314
+ @events << ActiveSupport::Notifications::Event.new(*args)
315
+ end
316
+ yield
317
+ ActiveSupport::Cache::RedisStore.instrument = false
318
+ end
319
+ end
320
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ describe Redis::ActiveSupport::VERSION do
4
+ it 'returns current version' do
5
+ Redis::ActiveSupport::VERSION.must_equal '4.0.0'
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha/setup'
4
+ require 'active_support'
5
+ require 'active_support/cache/redis_store'
6
+
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fault_tolerant_redis-activesupport
3
+ version: !ruby/object:Gem::Version
4
+ version: 4.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Luca Guidi
8
+ - Jan Renra Gloser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-11-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redis-store
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 1.1.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 1.1.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '4'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '4'
42
+ - !ruby/object:Gem::Dependency
43
+ name: maybe_client
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '='
47
+ - !ruby/object:Gem::Version
48
+ version: 1.1.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '='
54
+ - !ruby/object:Gem::Version
55
+ version: 1.1.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.3'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.3'
84
+ - !ruby/object:Gem::Dependency
85
+ name: mocha
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.14.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.14.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: minitest
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '4.2'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '4.2'
112
+ - !ruby/object:Gem::Dependency
113
+ name: redis-store-testing
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Fault tolerant redis store for ActiveSupport
127
+ email:
128
+ - me@lucaguidi.com
129
+ - jan.renra.gloser@gmail.com
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".env"
135
+ - ".gitignore"
136
+ - ".travis.yml"
137
+ - Gemfile
138
+ - MIT-LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - fault_tolerant_redis-activesupport.gemspec
142
+ - lib/active_support/cache/fault_tolerant_redis_store.rb
143
+ - lib/fault_tolerant_redis-activesupport.rb
144
+ - lib/redis/activesupport/version.rb
145
+ - test/active_support/cache/redis_store_test.rb
146
+ - test/redis/activesupport/version_test.rb
147
+ - test/test_helper.rb
148
+ homepage: https://github.com/renra/redis-activesupport
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project: redis-activesupport
168
+ rubygems_version: 2.4.5.1
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: Fault tolerant redis store for ActiveSupport
172
+ test_files:
173
+ - test/active_support/cache/redis_store_test.rb
174
+ - test/redis/activesupport/version_test.rb
175
+ - test/test_helper.rb