rack-revalidate-while-cache 0.0.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.
- data/README.rdoc +12 -0
- data/Rakefile +42 -0
- data/VERSION.yml +4 -0
- data/lib/rack_cache_while_revalidate.rb +41 -0
- data/rack-revalidate-while-cache.gemspec +46 -0
- data/spec/rack_cache_while_revalidate_spec.rb +39 -0
- data/spec/spec_helper.rb +12 -0
- metadata +62 -0
data/README.rdoc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
= Rack::CacheWhileRevalidate
|
2
|
+
|
3
|
+
== Idea
|
4
|
+
|
5
|
+
Often, for caching, you don't care if the data is a little stale, you're content to serve the stale data and silently revalidate the cache in the background.
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
In your builder (or rackup or whatever), make sure you first off:
|
10
|
+
<tt>use Rack::Capabilities</tt>
|
11
|
+
|
12
|
+
Then, wherever your <tt>Rack::Cache</tt> usage occurs, put <tt>use Rack::CacheWhileRevalidate</tt> directly before it (NB). That's it!
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rack-revalidate-while-cache"
|
8
|
+
gem.summary = %Q{Rack middleware for periodic cache regeneration}
|
9
|
+
gem.email = "joshbuddy@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/joshbuddy/rack-regenerate"
|
11
|
+
gem.authors = ["Joshua Hull"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
Jeweler::GemcutterTasks.new
|
15
|
+
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/rdoctask'
|
21
|
+
Rake::RDocTask.new do |rdoc|
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = 'rack-regenerate'
|
24
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
25
|
+
rdoc.rdoc_files.include('README*')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'spec/rake/spectask'
|
30
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
31
|
+
spec.libs << 'lib' << 'spec'
|
32
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
36
|
+
spec.libs << 'lib' << 'spec'
|
37
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
38
|
+
spec.rcov = true
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rack/cache'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class CacheWhileRevalidate
|
6
|
+
|
7
|
+
def initialize(app, debug = false)
|
8
|
+
@app = app
|
9
|
+
|
10
|
+
@queue = Queue.new
|
11
|
+
|
12
|
+
Thread.new do
|
13
|
+
while true
|
14
|
+
begin
|
15
|
+
env = @queue.pop
|
16
|
+
@app.call(env)
|
17
|
+
rescue Exception => e
|
18
|
+
puts "e: #{e.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(env)
|
25
|
+
|
26
|
+
cache = Rack::Capabilities.after(self)
|
27
|
+
request = Rack::Cache::Request.new(env.dup)
|
28
|
+
|
29
|
+
cache.instance_variable_set(:@request, request)
|
30
|
+
|
31
|
+
if (request.get? || request.head?) && !env['HTTP_EXPECT'] && (entry = cache.metastore.lookup(request, cache.entitystore)) && cache.send(:fresh_enough?, entry)
|
32
|
+
@queue << env
|
33
|
+
entry.to_a
|
34
|
+
else
|
35
|
+
@app.call(env)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rack-revalidate-while-cache}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Joshua Hull"]
|
12
|
+
s.date = %q{2009-12-03}
|
13
|
+
s.email = %q{joshbuddy@gmail.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README.rdoc"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
"README.rdoc",
|
19
|
+
"Rakefile",
|
20
|
+
"VERSION.yml",
|
21
|
+
"lib/rack_cache_while_revalidate.rb",
|
22
|
+
"rack-revalidate-while-cache.gemspec",
|
23
|
+
"spec/rack_cache_while_revalidate_spec.rb",
|
24
|
+
"spec/spec_helper.rb"
|
25
|
+
]
|
26
|
+
s.homepage = %q{http://github.com/joshbuddy/rack-regenerate}
|
27
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
s.rubygems_version = %q{1.3.5}
|
30
|
+
s.summary = %q{Rack middleware for periodic cache regeneration}
|
31
|
+
s.test_files = [
|
32
|
+
"spec/rack_cache_while_revalidate_spec.rb",
|
33
|
+
"spec/spec_helper.rb"
|
34
|
+
]
|
35
|
+
|
36
|
+
if s.respond_to? :specification_version then
|
37
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
38
|
+
s.specification_version = 3
|
39
|
+
|
40
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
41
|
+
else
|
42
|
+
end
|
43
|
+
else
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
def build_builder(app)
|
5
|
+
Rack::Builder.new {
|
6
|
+
|
7
|
+
use Rack::Capabilities
|
8
|
+
use Rack::CacheWhileRevalidate
|
9
|
+
use Rack::Cache,
|
10
|
+
:verbose => true,
|
11
|
+
:metastore => 'heap:/',
|
12
|
+
:entitystore => 'heap:/'
|
13
|
+
|
14
|
+
run app
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "Rack Cache While Revalidate" do
|
20
|
+
|
21
|
+
it "should pass uncached requests through normally" do
|
22
|
+
app = mock('app')
|
23
|
+
app.should_receive(:call).and_return [200, {}, ['oh yeah']]
|
24
|
+
|
25
|
+
builder = build_builder(app)
|
26
|
+
builder.call(Rack::MockRequest.env_for("http://127.0.0.1/testing")).last.should == ['oh yeah']
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should serve stale requests while continuing on with the original request" do
|
30
|
+
app = mock('app')
|
31
|
+
app.should_receive(:call).and_return { sleep(2); [200, {'Cache-Control' => 'max-age=1'}, ['oh yeah']]}
|
32
|
+
builder = build_builder(app)
|
33
|
+
builder.call(Rack::MockRequest.env_for("http://127.0.0.1/testing")).last.should == ['oh yeah']
|
34
|
+
start_time = Time.new.to_f
|
35
|
+
builder.call(Rack::MockRequest.env_for("http://127.0.0.1/testing")).last.should == ['oh yeah']
|
36
|
+
(Time.new.to_f - start_time).should < 1
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rack/cache'
|
4
|
+
require 'rack-capabilities'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
require 'rack_cache_while_revalidate'
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-revalidate-while-cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Hull
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-03 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: joshbuddy@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- VERSION.yml
|
28
|
+
- lib/rack_cache_while_revalidate.rb
|
29
|
+
- rack-revalidate-while-cache.gemspec
|
30
|
+
- spec/rack_cache_while_revalidate_spec.rb
|
31
|
+
- spec/spec_helper.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://github.com/joshbuddy/rack-regenerate
|
34
|
+
licenses: []
|
35
|
+
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --charset=UTF-8
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.3.5
|
57
|
+
signing_key:
|
58
|
+
specification_version: 3
|
59
|
+
summary: Rack middleware for periodic cache regeneration
|
60
|
+
test_files:
|
61
|
+
- spec/rack_cache_while_revalidate_spec.rb
|
62
|
+
- spec/spec_helper.rb
|