cachy 0.1.3 → 0.1.4
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.
- data/README.markdown +4 -4
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/cachy.gemspec +7 -8
- data/lib/cachy.rb +46 -8
- data/spec/cachy_spec.rb +126 -26
- metadata +14 -8
- data/rdoc/README.rdoc +0 -1
data/README.markdown
CHANGED
@@ -71,12 +71,15 @@ When they are updated the cache is automatically expired.
|
|
71
71
|
Use a global `CACHE_VERSION=1` so that all caches can be expired when something big changes.
|
72
72
|
The cache server does not need to be restarted and session data(Rails) is saved.
|
73
73
|
|
74
|
-
|
75
74
|
#### Does not cache nil
|
76
75
|
If you want to cache a falsy result, use false (same goes for :while_running)
|
77
76
|
Cachy.cache(:x){ expensive || false }
|
78
77
|
Cachy.cache(:x, :while_running=>false){ expensive }
|
79
78
|
|
79
|
+
###Cachy.cache_if
|
80
|
+
Only caches if condition is fulfilled
|
81
|
+
Cachy.cache_if(condition, :foo, 'bar', :expires_in => 1.minute){do_something}
|
82
|
+
|
80
83
|
###Cachy.expire / .expire_view
|
81
84
|
Expires all locales of a key
|
82
85
|
Cachy.locales = [:de, :en] # by default filled with I18n.available_locales
|
@@ -86,20 +89,17 @@ Expires all locales of a key
|
|
86
89
|
Cachy.expire_view(:my_key)
|
87
90
|
Cachy.expire(:my_key, :prefix=>'views/')
|
88
91
|
|
89
|
-
|
90
92
|
###Cachy.key
|
91
93
|
Use to cache e.g. Erb output
|
92
94
|
<% cache Cachy.key(:a_key), :expires_in=>1.hour do %>
|
93
95
|
More html ...
|
94
96
|
<% end %>
|
95
97
|
|
96
|
-
|
97
98
|
###Cachy.cache_store
|
98
99
|
No ActionController::Base.cache_store ?
|
99
100
|
Give me something that responds to read/write(Rails style) or []/store([Moneta](http://github.com/wycats/moneta/tree/master)) or get/set(Memcached)
|
100
101
|
Cachy.cache_store = some_cache
|
101
102
|
|
102
|
-
|
103
103
|
###Cachy.locales
|
104
104
|
No I18n.available_locales ?
|
105
105
|
Cachy.locales = [:de, :en, :fr]
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/cachy.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cachy}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Grosser"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-08-14}
|
13
13
|
s.email = %q{grosser.michael@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.markdown"
|
@@ -23,7 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
"lib/cachy/memcached_wrapper.rb",
|
24
24
|
"lib/cachy/moneta_wrapper.rb",
|
25
25
|
"lib/cachy/wrapper.rb",
|
26
|
-
"rdoc/README.rdoc",
|
27
26
|
"spec/cachy/memcached_wrapper_spec.rb",
|
28
27
|
"spec/cachy/moneta_wrapper_spec.rb",
|
29
28
|
"spec/cachy_spec.rb",
|
@@ -33,14 +32,14 @@ Gem::Specification.new do |s|
|
|
33
32
|
s.homepage = %q{http://github.com/grosser/cachy}
|
34
33
|
s.rdoc_options = ["--charset=UTF-8"]
|
35
34
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version = %q{1.3.
|
35
|
+
s.rubygems_version = %q{1.3.6}
|
37
36
|
s.summary = %q{Caching library for projects that have many processes or many caches}
|
38
37
|
s.test_files = [
|
39
|
-
"spec/
|
40
|
-
"spec/test_cache.rb",
|
41
|
-
"spec/cachy/memcached_wrapper_spec.rb",
|
38
|
+
"spec/cachy/memcached_wrapper_spec.rb",
|
42
39
|
"spec/cachy/moneta_wrapper_spec.rb",
|
43
|
-
"spec/cachy_spec.rb"
|
40
|
+
"spec/cachy_spec.rb",
|
41
|
+
"spec/test_cache.rb",
|
42
|
+
"spec/spec_helper.rb"
|
44
43
|
]
|
45
44
|
|
46
45
|
if s.respond_to? :specification_version then
|
data/lib/cachy.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
class Cachy
|
2
2
|
WHILE_RUNNING_TMEOUT = 5*60 #seconds
|
3
3
|
KEY_VERSION_TIMEOUT = 30 #seconds
|
4
|
+
HEALTH_CHECK_KEY = 'cachy_healthy'
|
5
|
+
KEY_VERSIONS_KEY = 'cachy_key_versions'
|
6
|
+
|
7
|
+
@@cache_error = false
|
4
8
|
|
5
9
|
# Cache the result of a block
|
6
10
|
#
|
@@ -13,7 +17,6 @@ class Cachy
|
|
13
17
|
key = key(*args)
|
14
18
|
options = extract_options!(args)
|
15
19
|
|
16
|
-
# Cached result?
|
17
20
|
result = cache_store.read(key)
|
18
21
|
return result unless result == nil
|
19
22
|
|
@@ -24,6 +27,14 @@ class Cachy
|
|
24
27
|
cache_store.write key, result, options
|
25
28
|
result
|
26
29
|
end
|
30
|
+
|
31
|
+
def self.cache_if(cond, *args, &block)
|
32
|
+
if cond
|
33
|
+
cache(*args, &block)
|
34
|
+
else
|
35
|
+
block.call
|
36
|
+
end
|
37
|
+
end
|
27
38
|
|
28
39
|
# Constructs a cache-key (first argument must be a String/Symbol)
|
29
40
|
#
|
@@ -43,7 +54,7 @@ class Cachy
|
|
43
54
|
end * "_"
|
44
55
|
|
45
56
|
key = (options[:hash_key] || hash_keys) ? hash(key) : key
|
46
|
-
options[:prefix].to_s + key + options[:suffix].to_s
|
57
|
+
(options[:prefix].to_s + key + options[:suffix].to_s).gsub(' ', '_')
|
47
58
|
end
|
48
59
|
|
49
60
|
# Expire all possible locales of a cache, use the same arguments as with cache
|
@@ -72,7 +83,7 @@ class Cachy
|
|
72
83
|
@@key_versions = {:versions=>{}, :last_set=>0}
|
73
84
|
def self.key_versions
|
74
85
|
if key_versions_expired?
|
75
|
-
versions =
|
86
|
+
versions = read_versions
|
76
87
|
@@key_versions = {:versions=>versions, :last_set=>Time.now.to_i}
|
77
88
|
end
|
78
89
|
@@key_versions[:versions]
|
@@ -80,22 +91,29 @@ class Cachy
|
|
80
91
|
|
81
92
|
def self.key_versions=(data)
|
82
93
|
@@key_versions[:last_set] = 0 #expire current key
|
83
|
-
|
94
|
+
write_version(data)
|
84
95
|
end
|
85
96
|
|
86
97
|
# Expires all caches that use this key
|
87
98
|
def self.increment_key(key)
|
88
99
|
key = key.to_sym
|
89
|
-
|
100
|
+
current_versions = read_versions
|
101
|
+
version = current_versions[key] || 0
|
90
102
|
version += 1
|
91
|
-
self.key_versions =
|
103
|
+
self.key_versions = current_versions.merge(key => version)
|
92
104
|
version
|
93
105
|
end
|
94
106
|
|
107
|
+
def self.delete_key(key)
|
108
|
+
versions = key_versions.dup
|
109
|
+
versions.delete(key.to_sym)
|
110
|
+
self.key_versions = versions
|
111
|
+
end
|
112
|
+
|
95
113
|
class << self
|
96
114
|
attr_accessor :hash_keys
|
97
115
|
end
|
98
|
-
|
116
|
+
|
99
117
|
# Wrap non ActiveSupport style cache stores,
|
100
118
|
# to get the same interface for all
|
101
119
|
def self.cache_store=(x)
|
@@ -110,6 +128,7 @@ class Cachy
|
|
110
128
|
else
|
111
129
|
raise "This cache_store type is not usable for Cachy!"
|
112
130
|
end
|
131
|
+
@cache_store.write HEALTH_CHECK_KEY, 'yes'
|
113
132
|
end
|
114
133
|
|
115
134
|
def self.cache_store
|
@@ -135,6 +154,25 @@ class Cachy
|
|
135
154
|
|
136
155
|
private
|
137
156
|
|
157
|
+
def self.read_versions
|
158
|
+
data = cache_store.instance_variable_get('@data')
|
159
|
+
if data.respond_to? :read_error_occured # its a MemCache with read_error detection !
|
160
|
+
result = data[KEY_VERSIONS_KEY] || {}
|
161
|
+
@@cache_error = data.read_error_occured
|
162
|
+
result
|
163
|
+
else
|
164
|
+
cache_store.read(KEY_VERSIONS_KEY) || {}
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.write_version(data)
|
169
|
+
cache_store.write(KEY_VERSIONS_KEY, data) unless @@cache_error
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.cache_healthy?
|
173
|
+
cache_store.read(HEALTH_CHECK_KEY) == 'yes'
|
174
|
+
end
|
175
|
+
|
138
176
|
# Do we need to fetch fresh key_versions from cache ?
|
139
177
|
def self.key_versions_expired?
|
140
178
|
key_versions_timeout = Time.now.to_i - KEY_VERSION_TIMEOUT
|
@@ -167,7 +205,7 @@ class Cachy
|
|
167
205
|
|
168
206
|
def self.key_version_for(key)
|
169
207
|
key = key.to_sym
|
170
|
-
key_versions[key] || increment_key(key)
|
208
|
+
key_versions[key] || (cache_healthy? ? increment_key(key) : 1)
|
171
209
|
end
|
172
210
|
|
173
211
|
def self.ensure_valid_keys(options)
|
data/spec/cachy_spec.rb
CHANGED
@@ -1,27 +1,25 @@
|
|
1
1
|
require 'spec/spec_helper'
|
2
2
|
|
3
|
-
TEST_CACHE = TestCache.new
|
4
|
-
|
5
3
|
describe Cachy do
|
6
|
-
before :all do
|
7
|
-
Cachy.cache_store = TEST_CACHE
|
8
|
-
end
|
9
|
-
|
10
4
|
before do
|
11
|
-
|
5
|
+
@cache = TestCache.new
|
6
|
+
Cachy.cache_store = @cache
|
7
|
+
Cachy.class_eval "@@key_versions = {:versions=>{}, :last_set=>0}"
|
8
|
+
@cache.write(Cachy::HEALTH_CHECK_KEY, 'yes')
|
9
|
+
Cachy.send(:class_variable_set, '@@cache_error', false)
|
12
10
|
end
|
13
|
-
|
11
|
+
|
14
12
|
describe :cache do
|
15
13
|
it "caches" do
|
16
14
|
Cachy.cache(:my_key){ "X" }.should == "X"
|
17
15
|
Cachy.cache(:my_key){ "ABC" }.should == "X"
|
18
16
|
end
|
19
|
-
|
17
|
+
|
20
18
|
it "expires" do
|
21
19
|
Cachy.cache(:his_key, :expires_in=> -100){ 'X' }.should == 'X'
|
22
20
|
Cachy.cache(:his_key, :expires_in=> -100){ 'X' }.should == 'X'
|
23
21
|
end
|
24
|
-
|
22
|
+
|
25
23
|
it "sets cache to intermediate value while running expensive query" do
|
26
24
|
Cachy.cache(:my_key, :while_running=>'A') do
|
27
25
|
Cachy.cache(:my_key){ 'X' }.should == 'A'
|
@@ -51,6 +49,29 @@ describe Cachy do
|
|
51
49
|
Cachy.cache(:x){ true }.should == true
|
52
50
|
end
|
53
51
|
end
|
52
|
+
|
53
|
+
describe :cache_if do
|
54
|
+
it "should not call the cache command if condition is wrong" do
|
55
|
+
Cachy.should_not_receive(:cache)
|
56
|
+
Cachy.cache_if(false, :x) do
|
57
|
+
"asd"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should call cache command if condition is true" do
|
62
|
+
Cachy.should_receive(:cache)
|
63
|
+
Cachy.cache_if(true, :x) do
|
64
|
+
"asd"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should pass params correctly" do
|
69
|
+
Cachy.should_receive(:cache).with(:x, {:y => 1}, :expires_in => 3)
|
70
|
+
Cachy.cache_if(true, :x, {:y => 1}, :expires_in => 3) do
|
71
|
+
"asd"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
54
75
|
|
55
76
|
describe :expire do
|
56
77
|
it "expires the cache for all languages" do
|
@@ -62,10 +83,10 @@ describe Cachy do
|
|
62
83
|
Cachy.cache(:my_key){ l }
|
63
84
|
end
|
64
85
|
|
65
|
-
|
86
|
+
@cache.keys.select{|k| k=~ /my_key/}.size.should == 4
|
66
87
|
Cachy.stub!(:locales).and_return locales
|
67
88
|
Cachy.expire(:my_key)
|
68
|
-
|
89
|
+
@cache.keys.select{|k| k=~ /my_key/}.size.should == 0
|
69
90
|
end
|
70
91
|
|
71
92
|
it "does not expire other keys" do
|
@@ -73,35 +94,35 @@ describe Cachy do
|
|
73
94
|
Cachy.cache(:my_key){ 'X' }
|
74
95
|
Cachy.cache(:yet_another_key){ 'X' }
|
75
96
|
Cachy.expire :my_key
|
76
|
-
|
77
|
-
|
97
|
+
@cache.keys.should include("another_key_v1")
|
98
|
+
@cache.keys.should include("yet_another_key_v1")
|
78
99
|
end
|
79
100
|
|
80
101
|
it "expires the cache when no available_locales are set" do
|
81
102
|
Cachy.cache(:another_key){ "X" }
|
82
103
|
Cachy.cache(:my_key){ "X" }
|
83
104
|
|
84
|
-
|
105
|
+
@cache.keys.select{|k| k=~ /my_key/}.size.should == 1
|
85
106
|
Cachy.expire(:my_key)
|
86
|
-
|
107
|
+
@cache.keys.select{|k| k=~ /my_key/}.size.should == 0
|
87
108
|
end
|
88
109
|
|
89
110
|
it "expires the cache with prefix" do
|
90
111
|
key = 'views/my_key_v1'
|
91
|
-
|
92
|
-
|
112
|
+
@cache.write(key, 'x')
|
113
|
+
@cache.read(key).should_not == nil
|
93
114
|
Cachy.expire(:my_key, :prefix=>'views/')
|
94
|
-
|
115
|
+
@cache.read(key).should == nil
|
95
116
|
end
|
96
117
|
end
|
97
118
|
|
98
119
|
describe :expire_view do
|
99
120
|
it "expires the cache with prefix" do
|
100
121
|
key = 'views/my_key_v1'
|
101
|
-
|
102
|
-
|
122
|
+
@cache.write(key, 'x')
|
123
|
+
@cache.read(key).should_not == nil
|
103
124
|
Cachy.expire_view(:my_key)
|
104
|
-
|
125
|
+
@cache.read(key).should == nil
|
105
126
|
end
|
106
127
|
end
|
107
128
|
|
@@ -121,11 +142,15 @@ describe Cachy do
|
|
121
142
|
end
|
122
143
|
|
123
144
|
it "gets the locale from I18n" do
|
124
|
-
module I18n
|
145
|
+
# a bit weird but just module I18n does not work with 1.9.1
|
146
|
+
i18n = Module.new
|
147
|
+
i18n.class_eval do
|
125
148
|
def self.locale
|
126
149
|
:de
|
127
150
|
end
|
128
151
|
end
|
152
|
+
Object.const_set :I18n, i18n
|
153
|
+
|
129
154
|
key = Cachy.key(:x)
|
130
155
|
Object.send :remove_const, :I18n #cleanup
|
131
156
|
key.should == "x_v1_de"
|
@@ -205,13 +230,24 @@ describe Cachy do
|
|
205
230
|
|
206
231
|
describe :key_versions do
|
207
232
|
before do
|
208
|
-
Cachy.key_versions =
|
233
|
+
Cachy.key_versions = nil
|
209
234
|
Cachy.key_versions.should == {}
|
210
235
|
end
|
211
236
|
|
237
|
+
it "merges in old when setting new" do
|
238
|
+
pending '!!!!!'
|
239
|
+
end
|
240
|
+
|
212
241
|
it "adds a key when cache is called the first time" do
|
213
242
|
Cachy.cache(:xxx){1}
|
214
243
|
Cachy.key_versions[:xxx].should == 1
|
244
|
+
@cache.read(Cachy::KEY_VERSIONS_KEY).should_not == nil
|
245
|
+
end
|
246
|
+
|
247
|
+
it "does not add a key when cache is called the first time and cache is not healthy" do
|
248
|
+
@cache.write(Cachy::HEALTH_CHECK_KEY, 'no')
|
249
|
+
Cachy.cache(:xxx){1}
|
250
|
+
@cache.read(Cachy::KEY_VERSIONS_KEY).should == nil
|
215
251
|
end
|
216
252
|
|
217
253
|
it "adds a string key as symbol" do
|
@@ -228,13 +264,13 @@ describe Cachy do
|
|
228
264
|
|
229
265
|
it "reloads when keys have expired" do
|
230
266
|
Cachy.send :class_variable_set, "@@key_versions", {:versions=>{:xx=>2}, :last_set=>(Time.now.to_i - 60)}
|
231
|
-
|
267
|
+
@cache.write Cachy::KEY_VERSIONS_KEY, {:xx=>1}
|
232
268
|
Cachy.key_versions.should == {:xx=>1}
|
233
269
|
end
|
234
270
|
|
235
271
|
it "does not reload when keys have not expired" do
|
236
272
|
Cachy.send :class_variable_set, "@@key_versions", {:versions=>{:xx=>2}, :last_set=>Time.now.to_i}
|
237
|
-
|
273
|
+
@cache.write Cachy::KEY_VERSIONS_KEY, {:xx=>1}
|
238
274
|
Cachy.key_versions.should == {:xx=>2}
|
239
275
|
end
|
240
276
|
|
@@ -244,4 +280,68 @@ describe Cachy do
|
|
244
280
|
Cachy.key_versions[:xx].should == 1
|
245
281
|
end
|
246
282
|
end
|
283
|
+
|
284
|
+
describe :key_versions, "with timeout" do
|
285
|
+
before do
|
286
|
+
@mock = mock = {}
|
287
|
+
@cache.instance_eval{@data = mock}
|
288
|
+
def @mock.read_error_occured
|
289
|
+
false
|
290
|
+
end
|
291
|
+
def @mock.[](x)
|
292
|
+
{:x => 1}
|
293
|
+
end
|
294
|
+
Cachy.send(:class_variable_set, '@@cache_error', false)
|
295
|
+
end
|
296
|
+
|
297
|
+
it "reads normally" do
|
298
|
+
Cachy.send(:read_versions).should == {:x => 1}
|
299
|
+
end
|
300
|
+
|
301
|
+
it "reads empty when it crashes" do
|
302
|
+
@mock.should_receive(:[]).and_return nil # e.g. Timout happended
|
303
|
+
@mock.should_receive(:read_error_occured).and_return true
|
304
|
+
Cachy.send(:read_versions).should == {}
|
305
|
+
end
|
306
|
+
|
307
|
+
it "marks as error when it crashes" do
|
308
|
+
Cachy.send(:class_variable_get, '@@cache_error').should == false
|
309
|
+
@mock.should_receive(:read_error_occured).and_return true
|
310
|
+
Cachy.send(:read_versions)
|
311
|
+
Cachy.send(:class_variable_get, '@@cache_error').should == true
|
312
|
+
end
|
313
|
+
|
314
|
+
it "marks as error free when it reads successfully" do
|
315
|
+
Cachy.send(:class_variable_set, '@@cache_error', true)
|
316
|
+
Cachy.send(:class_variable_get, '@@cache_error').should == true
|
317
|
+
Cachy.send(:read_versions).should == {:x => 1}
|
318
|
+
Cachy.send(:class_variable_get, '@@cache_error').should == false
|
319
|
+
end
|
320
|
+
|
321
|
+
it "writes when it was not error before" do
|
322
|
+
Cachy.cache_store.should_receive(:write)
|
323
|
+
Cachy.send(:write_version, {})
|
324
|
+
end
|
325
|
+
|
326
|
+
it "does not write when it was error before" do
|
327
|
+
Cachy.send(:class_variable_set, '@@cache_error', true)
|
328
|
+
Cachy.cache_store.should_not_receive(:write)
|
329
|
+
Cachy.send(:write_version, {})
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe :delete_key do
|
334
|
+
it "removes a key from key versions" do
|
335
|
+
Cachy.cache(:xxx){1}
|
336
|
+
Cachy.key_versions.key?(:xxx).should == true
|
337
|
+
Cachy.delete_key :xxx
|
338
|
+
Cachy.key_versions.key?(:xxx).should == false
|
339
|
+
end
|
340
|
+
|
341
|
+
it "does not crash with unfound key" do
|
342
|
+
Cachy.delete_key :xxx
|
343
|
+
Cachy.delete_key :xxx
|
344
|
+
Cachy.key_versions.key?(:xxx).should == false
|
345
|
+
end
|
346
|
+
end
|
247
347
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cachy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 4
|
9
|
+
version: 0.1.4
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Michael Grosser
|
@@ -9,7 +14,7 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date:
|
17
|
+
date: 2010-08-14 00:00:00 +02:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
@@ -30,7 +35,6 @@ files:
|
|
30
35
|
- lib/cachy/memcached_wrapper.rb
|
31
36
|
- lib/cachy/moneta_wrapper.rb
|
32
37
|
- lib/cachy/wrapper.rb
|
33
|
-
- rdoc/README.rdoc
|
34
38
|
- spec/cachy/memcached_wrapper_spec.rb
|
35
39
|
- spec/cachy/moneta_wrapper_spec.rb
|
36
40
|
- spec/cachy_spec.rb
|
@@ -49,24 +53,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
53
|
requirements:
|
50
54
|
- - ">="
|
51
55
|
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
52
58
|
version: "0"
|
53
|
-
version:
|
54
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
60
|
requirements:
|
56
61
|
- - ">="
|
57
62
|
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
58
65
|
version: "0"
|
59
|
-
version:
|
60
66
|
requirements: []
|
61
67
|
|
62
68
|
rubyforge_project:
|
63
|
-
rubygems_version: 1.3.
|
69
|
+
rubygems_version: 1.3.6
|
64
70
|
signing_key:
|
65
71
|
specification_version: 3
|
66
72
|
summary: Caching library for projects that have many processes or many caches
|
67
73
|
test_files:
|
68
|
-
- spec/spec_helper.rb
|
69
|
-
- spec/test_cache.rb
|
70
74
|
- spec/cachy/memcached_wrapper_spec.rb
|
71
75
|
- spec/cachy/moneta_wrapper_spec.rb
|
72
76
|
- spec/cachy_spec.rb
|
77
|
+
- spec/test_cache.rb
|
78
|
+
- spec/spec_helper.rb
|
data/rdoc/README.rdoc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
documentation is at http://github.com/grosser/cachy
|