rack-cache 0.5 → 0.5.2
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.
Potentially problematic release.
This version of rack-cache might be problematic. Click here for more details.
- data/CHANGES +15 -0
- data/Rakefile +9 -1
- data/doc/storage.markdown +16 -14
- data/lib/rack/cache/context.rb +32 -12
- data/lib/rack/cache/entitystore.rb +18 -12
- data/lib/rack/cache/metastore.rb +21 -13
- data/lib/rack/cache/storage.rb +18 -5
- data/rack-cache.gemspec +2 -2
- data/test/context_test.rb +25 -0
- data/test/metastore_test.rb +4 -4
- data/test/options_test.rb +0 -1
- data/test/spec_setup.rb +1 -2
- metadata +5 -3
data/CHANGES
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.6.0 / Unreleased
|
2
|
+
|
3
|
+
* Added support for memcached clusters and other advanced
|
4
|
+
configuration provided by the memcache-client and memcached
|
5
|
+
libraries. The "metastore" and "entitystore" options can now be
|
6
|
+
set to a MemCache object or Memcached object:
|
7
|
+
|
8
|
+
memcache = MemCache.new(['127.1.1.1', '127.1.1.2'], :namespace => "/foo")
|
9
|
+
use Rack::Cache,
|
10
|
+
:metastore => memcache,
|
11
|
+
:entitystore => memcache
|
12
|
+
|
13
|
+
* Fix "memcached://" metastore URL handling. The "memcached" variation
|
14
|
+
blew up, the "memcache" version was fine.
|
15
|
+
|
1
16
|
## 0.5.0 / May 2009
|
2
17
|
|
3
18
|
* Added meta and entity store implementations based on the
|
data/Rakefile
CHANGED
@@ -110,13 +110,21 @@ file package('.tar.gz') => %w[dist/] + $spec.files do |f|
|
|
110
110
|
end
|
111
111
|
|
112
112
|
desc 'Upload gem and tar.gz distributables to rubyforge'
|
113
|
-
task :
|
113
|
+
task 'release:rubyforge' => [package('.gem'), package('.tar.gz')] do |t|
|
114
114
|
sh <<-SH
|
115
115
|
rubyforge add_release wink rack-cache #{$spec.version} #{package('.gem')} &&
|
116
116
|
rubyforge add_file wink rack-cache #{$spec.version} #{package('.tar.gz')}
|
117
117
|
SH
|
118
118
|
end
|
119
119
|
|
120
|
+
desc 'Upload gem to gemcutter.org'
|
121
|
+
task 'release:gemcutter' => [package('.gem')] do |t|
|
122
|
+
sh "gem push #{package('.gem')}"
|
123
|
+
end
|
124
|
+
|
125
|
+
desc 'Upload gem to gemcutter and rubyforge'
|
126
|
+
task 'release' => ['release:gemcutter', 'release:rubyforge']
|
127
|
+
|
120
128
|
# GEMSPEC ===================================================================
|
121
129
|
|
122
130
|
file 'rack-cache.gemspec' => FileList['{lib,test}/**','Rakefile'] do |f|
|
data/doc/storage.markdown
CHANGED
@@ -62,10 +62,9 @@ deployments so explicit configuration is advised.
|
|
62
62
|
The default metastore and entitystore values can be specified when the
|
63
63
|
__Rack::Cache__ object is added to the Rack middleware pipeline as follows:
|
64
64
|
|
65
|
-
use Rack::Cache
|
66
|
-
|
67
|
-
|
68
|
-
end
|
65
|
+
use Rack::Cache,
|
66
|
+
:metastore => 'file:/var/cache/rack/meta',
|
67
|
+
:entitystore => 'file:/var/cache/rack/body'
|
69
68
|
|
70
69
|
Alternatively, the `rack-cache.metastore` and `rack-cache.entitystore`
|
71
70
|
variables may be set in the Rack environment by an upstream component.
|
@@ -82,8 +81,9 @@ use a specific storage implementation as well as pros and cons of each.
|
|
82
81
|
|
83
82
|
Uses local process memory to store cached entries.
|
84
83
|
|
85
|
-
|
86
|
-
|
84
|
+
use Rack::Cache,
|
85
|
+
:metastore => 'heap:/',
|
86
|
+
:entitystore => 'heap:/'
|
87
87
|
|
88
88
|
The heap storage backend is simple, fast, and mostly useless. All cache
|
89
89
|
information is stored in each backend application's local process memory (using
|
@@ -102,8 +102,9 @@ is small and well understood.
|
|
102
102
|
|
103
103
|
Stores cached entries on the filesystem.
|
104
104
|
|
105
|
-
|
106
|
-
|
105
|
+
use Rack::Cache,
|
106
|
+
:metastore => 'file:/var/cache/rack/meta',
|
107
|
+
:entitystore => 'file:/var/cache/rack/body'
|
107
108
|
|
108
109
|
The URI may specify an absolute, relative, or home-rooted path:
|
109
110
|
|
@@ -132,18 +133,19 @@ collision.
|
|
132
133
|
Stores cached entries in a remote [memcached](http://www.danga.com/memcached/)
|
133
134
|
instance.
|
134
135
|
|
135
|
-
|
136
|
-
|
136
|
+
use Rack::Cache,
|
137
|
+
:metastore => 'memcached://localhost:11211/meta',
|
138
|
+
:entitystore => 'memcached://localhost:11211/body'
|
137
139
|
|
138
140
|
The URI must specify the host and port of a remote memcached daemon. The path
|
139
141
|
portion is an optional (but recommended) namespace that is prepended to each
|
140
142
|
cache key.
|
141
143
|
|
142
|
-
The memcached storage backend requires
|
143
|
-
|
144
|
-
|
144
|
+
The memcached storage backend requires either the `memcache-client` or
|
145
|
+
`memcached` libraries. By default, the `memcache-client` library is used;
|
146
|
+
require the `memcached` library explicitly to use it instead.
|
145
147
|
|
146
|
-
|
148
|
+
gem install memcache-client
|
147
149
|
|
148
150
|
Memcached storage is reasonably fast and allows multiple backends to share a
|
149
151
|
single cache. It is also the only storage implementation that allows the cache
|
data/lib/rack/cache/context.rb
CHANGED
@@ -133,8 +133,12 @@ module Rack::Cache
|
|
133
133
|
# Invalidate POST, PUT, DELETE and all methods not understood by this cache
|
134
134
|
# See RFC2616 13.10
|
135
135
|
def invalidate
|
136
|
-
record :invalidate
|
137
136
|
metastore.invalidate(@request, entitystore)
|
137
|
+
rescue Exception => e
|
138
|
+
log_error(e)
|
139
|
+
pass
|
140
|
+
else
|
141
|
+
record :invalidate
|
138
142
|
pass
|
139
143
|
end
|
140
144
|
|
@@ -147,18 +151,26 @@ module Rack::Cache
|
|
147
151
|
if @request.no_cache? && allow_reload?
|
148
152
|
record :reload
|
149
153
|
fetch
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
154
|
+
else
|
155
|
+
begin
|
156
|
+
entry = metastore.lookup(@request, entitystore)
|
157
|
+
rescue Exception => e
|
158
|
+
log_error(e)
|
159
|
+
return pass
|
160
|
+
end
|
161
|
+
if entry
|
162
|
+
if fresh_enough?(entry)
|
163
|
+
record :fresh
|
164
|
+
entry.headers['Age'] = entry.age.to_s
|
165
|
+
entry
|
166
|
+
else
|
167
|
+
record :stale
|
168
|
+
validate(entry)
|
169
|
+
end
|
155
170
|
else
|
156
|
-
record :
|
157
|
-
|
171
|
+
record :miss
|
172
|
+
fetch
|
158
173
|
end
|
159
|
-
else
|
160
|
-
record :miss
|
161
|
-
fetch
|
162
174
|
end
|
163
175
|
end
|
164
176
|
|
@@ -225,9 +237,17 @@ module Rack::Cache
|
|
225
237
|
|
226
238
|
# Write the response to the cache.
|
227
239
|
def store(response)
|
228
|
-
record :store
|
229
240
|
metastore.store(@request, response, entitystore)
|
230
241
|
response.headers['Age'] = response.age.to_s
|
242
|
+
rescue Exception => e
|
243
|
+
log_error(e)
|
244
|
+
nil
|
245
|
+
else
|
246
|
+
record :store
|
247
|
+
end
|
248
|
+
|
249
|
+
def log_error(exception)
|
250
|
+
@env['rack.errors'].write("cache error: #{exception.message}\n#{exception.backtrace.join("\n")}\n")
|
231
251
|
end
|
232
252
|
end
|
233
253
|
end
|
@@ -182,19 +182,25 @@ module Rack::Cache
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def self.resolve(uri)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
185
|
+
if uri.respond_to?(:scheme)
|
186
|
+
server = "#{uri.host}:#{uri.port || '11211'}"
|
187
|
+
options = parse_query(uri.query)
|
188
|
+
options.keys.each do |key|
|
189
|
+
value =
|
190
|
+
case value = options.delete(key)
|
191
|
+
when 'true' ; true
|
192
|
+
when 'false' ; false
|
193
|
+
else value.to_sym
|
194
|
+
end
|
195
|
+
options[k.to_sym] = value
|
196
|
+
end
|
197
|
+
options[:namespace] = uri.path.sub(/^\//, '')
|
198
|
+
new server, options
|
199
|
+
else
|
200
|
+
# if the object provided is not a URI, pass it straight through
|
201
|
+
# to the underlying implementation.
|
202
|
+
new uri
|
195
203
|
end
|
196
|
-
options[:namespace] = uri.path.sub(/^\//, '')
|
197
|
-
new server, options
|
198
204
|
end
|
199
205
|
end
|
200
206
|
|
data/lib/rack/cache/metastore.rb
CHANGED
@@ -274,19 +274,27 @@ module Rack::Cache
|
|
274
274
|
# Query parameter names and values are documented with the memcached
|
275
275
|
# library: http://tinyurl.com/4upqnd
|
276
276
|
def self.resolve(uri)
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
277
|
+
if uri.respond_to?(:scheme)
|
278
|
+
server = "#{uri.host}:#{uri.port || '11211'}"
|
279
|
+
options = parse_query(uri.query)
|
280
|
+
options.keys.each do |key|
|
281
|
+
value =
|
282
|
+
case value = options.delete(key)
|
283
|
+
when 'true' ; true
|
284
|
+
when 'false' ; false
|
285
|
+
else value.to_sym
|
286
|
+
end
|
287
|
+
options[k.to_sym] = value
|
288
|
+
end
|
289
|
+
|
290
|
+
options[:namespace] = uri.path.to_s.sub(/^\//, '')
|
291
|
+
|
292
|
+
new server, options
|
293
|
+
else
|
294
|
+
# if the object provided is not a URI, pass it straight through
|
295
|
+
# to the underlying implementation.
|
296
|
+
new uri
|
287
297
|
end
|
288
|
-
options[:namespace] = uri.path.sub(/^\//, '')
|
289
|
-
new server, options
|
290
298
|
end
|
291
299
|
end
|
292
300
|
|
@@ -359,7 +367,7 @@ module Rack::Cache
|
|
359
367
|
else
|
360
368
|
MemCache
|
361
369
|
end
|
362
|
-
MEMCACHED =
|
370
|
+
MEMCACHED = MEMCACHE
|
363
371
|
|
364
372
|
class GAEStore < MetaStore
|
365
373
|
attr_reader :cache
|
data/lib/rack/cache/storage.rb
CHANGED
@@ -30,12 +30,25 @@ module Rack::Cache
|
|
30
30
|
|
31
31
|
private
|
32
32
|
def create_store(type, uri)
|
33
|
-
uri
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
if uri.respond_to?(:scheme) || uri.respond_to?(:to_str)
|
34
|
+
uri = URI.parse(uri) unless uri.respond_to?(:scheme)
|
35
|
+
if type.const_defined?(uri.scheme.upcase)
|
36
|
+
klass = type.const_get(uri.scheme.upcase)
|
37
|
+
klass.resolve(uri)
|
38
|
+
else
|
39
|
+
fail "Unknown storage provider: #{uri.to_s}"
|
40
|
+
end
|
37
41
|
else
|
38
|
-
|
42
|
+
# hack in support for passing a MemCache or Memcached object
|
43
|
+
# as the storage URI.
|
44
|
+
case
|
45
|
+
when defined?(::MemCache) && uri.kind_of?(::MemCache)
|
46
|
+
type.const_get(:MemCache).resolve(uri)
|
47
|
+
when defined?(::Memcached) && uri.respond_to?(:stats)
|
48
|
+
type.const_get(:MemCached).resolve(uri)
|
49
|
+
else
|
50
|
+
fail "Unknown storage provider: #{uri.to_s}"
|
51
|
+
end
|
39
52
|
end
|
40
53
|
end
|
41
54
|
|
data/rack-cache.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
4
|
|
5
5
|
s.name = 'rack-cache'
|
6
|
-
s.version = '0.5'
|
7
|
-
s.date = '2009-
|
6
|
+
s.version = '0.5.2'
|
7
|
+
s.date = '2009-09-25'
|
8
8
|
|
9
9
|
s.description = "HTTP Caching for Rack"
|
10
10
|
s.summary = "HTTP Caching for Rack"
|
data/test/context_test.rb
CHANGED
@@ -746,4 +746,29 @@ describe 'Rack::Cache::Context' do
|
|
746
746
|
response['X-Response-Count'].should.equal '3'
|
747
747
|
end
|
748
748
|
end
|
749
|
+
|
750
|
+
it 'passes if there was a metastore exception' do
|
751
|
+
respond_with 200, 'Cache-Control' => 'max-age=10000' do |req,res|
|
752
|
+
res.body = ['Hello World']
|
753
|
+
end
|
754
|
+
|
755
|
+
get '/'
|
756
|
+
response.should.be.ok
|
757
|
+
response.body.should.equal 'Hello World'
|
758
|
+
cache.trace.should.include :store
|
759
|
+
|
760
|
+
get '/' do |cache|
|
761
|
+
cache.meta_def(:metastore) { raise Timeout::Error }
|
762
|
+
end
|
763
|
+
response.should.be.ok
|
764
|
+
response.body.should.equal 'Hello World'
|
765
|
+
cache.trace.should.include :pass
|
766
|
+
|
767
|
+
post '/' do |cache|
|
768
|
+
cache.meta_def(:metastore) { raise Timeout::Error }
|
769
|
+
end
|
770
|
+
response.should.be.ok
|
771
|
+
response.body.should.equal 'Hello World'
|
772
|
+
cache.trace.should.include :pass
|
773
|
+
end
|
749
774
|
end
|
data/test/metastore_test.rb
CHANGED
@@ -272,7 +272,7 @@ describe 'Rack::Cache::MetaStore' do
|
|
272
272
|
end
|
273
273
|
end
|
274
274
|
end
|
275
|
-
|
275
|
+
|
276
276
|
need_java 'entity store testing' do
|
277
277
|
module Rack::Cache::AppEngine
|
278
278
|
module MC
|
@@ -282,12 +282,12 @@ describe 'Rack::Cache::MetaStore' do
|
|
282
282
|
def get(key); self[key]; end;
|
283
283
|
def put(key, value, ttl = nil)
|
284
284
|
self[key] = value
|
285
|
-
end
|
285
|
+
end
|
286
286
|
|
287
287
|
end
|
288
288
|
end
|
289
289
|
end
|
290
|
-
|
290
|
+
|
291
291
|
describe 'GAEStore' do
|
292
292
|
it_should_behave_like 'A Rack::Cache::MetaStore Implementation'
|
293
293
|
before :each do
|
@@ -296,7 +296,7 @@ describe 'Rack::Cache::MetaStore' do
|
|
296
296
|
@entity_store = Rack::Cache::EntityStore::Heap.new
|
297
297
|
end
|
298
298
|
end
|
299
|
-
|
299
|
+
|
300
300
|
end
|
301
301
|
|
302
302
|
end
|
data/test/options_test.rb
CHANGED
data/test/spec_setup.rb
CHANGED
@@ -13,7 +13,7 @@ end
|
|
13
13
|
|
14
14
|
# Set the MEMCACHED environment variable as follows to enable testing
|
15
15
|
# of the MemCached meta and entity stores.
|
16
|
-
ENV['MEMCACHED'] ||= 'localhost:
|
16
|
+
ENV['MEMCACHED'] ||= 'localhost:11211'
|
17
17
|
$memcached = nil
|
18
18
|
$memcache = nil
|
19
19
|
|
@@ -70,7 +70,6 @@ def need_memcache(forwhat)
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def need_java(forwhat)
|
73
|
-
|
74
73
|
if RUBY_PLATFORM =~ /java/
|
75
74
|
yield
|
76
75
|
else
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Tomayko
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-25 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -75,6 +75,8 @@ files:
|
|
75
75
|
- test/storage_test.rb
|
76
76
|
has_rdoc: true
|
77
77
|
homepage: http://tomayko.com/src/rack-cache/
|
78
|
+
licenses: []
|
79
|
+
|
78
80
|
post_install_message:
|
79
81
|
rdoc_options:
|
80
82
|
- --line-numbers
|
@@ -100,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
102
|
requirements: []
|
101
103
|
|
102
104
|
rubyforge_project: wink
|
103
|
-
rubygems_version: 1.3.
|
105
|
+
rubygems_version: 1.3.4
|
104
106
|
signing_key:
|
105
107
|
specification_version: 2
|
106
108
|
summary: HTTP Caching for Rack
|