background_cache 0.1.1 → 0.1.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.
- data/lib/background_cache/config.rb +40 -47
- data/lib/background_cache/controller.rb +8 -25
- data/lib/background_cache/helper.rb +16 -14
- data/lib/background_cache.rb +7 -14
- data/require.rb +1 -1
- data/spec/background_cache_spec.rb +45 -26
- data/spec/fixtures/rails/config/routes.rb +1 -0
- data/spec/spec_helper.rb +11 -0
- metadata +37 -13
@@ -2,6 +2,9 @@ require 'digest/sha2'
|
|
2
2
|
|
3
3
|
module BackgroundCache
|
4
4
|
class Config
|
5
|
+
class <<self
|
6
|
+
attr_accessor :manual
|
7
|
+
end
|
5
8
|
def initialize(&block)
|
6
9
|
@@caches = []
|
7
10
|
self.instance_eval &block
|
@@ -49,48 +52,53 @@ module BackgroundCache
|
|
49
52
|
params = controller.params
|
50
53
|
params.delete 'background_cache'
|
51
54
|
path = controller.request.env['REQUEST_URI'].gsub(/[&?]background_cache=.+/, '')
|
52
|
-
|
53
|
-
@@caches
|
54
|
-
|
55
|
-
|
56
|
-
(
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# No fragment specified
|
61
|
-
fragment.empty? ||
|
55
|
+
cache =
|
56
|
+
if defined?(@@caches) && !@@caches.empty?
|
57
|
+
@@caches.detect do |item|
|
58
|
+
# Basic params match (action, controller, etc)
|
59
|
+
(
|
60
|
+
(item[:path] && item[:path] == path) ||
|
61
|
+
item[:params] == params.symbolize_keys
|
62
|
+
) &&
|
62
63
|
(
|
64
|
+
# No fragment specified
|
65
|
+
fragment.empty? ||
|
63
66
|
(
|
64
|
-
# :only not defined
|
65
|
-
!item[:only] ||
|
66
|
-
# :only matches fragment
|
67
|
-
item[:only] == fragment ||
|
68
67
|
(
|
69
|
-
# :only
|
70
|
-
item[:only]
|
71
|
-
# :only
|
72
|
-
item[:only]
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
68
|
+
# :only not defined
|
69
|
+
!item[:only] ||
|
70
|
+
# :only matches fragment
|
71
|
+
item[:only] == fragment ||
|
72
|
+
(
|
73
|
+
# :only is an array
|
74
|
+
item[:only].respond_to?(:index) &&
|
75
|
+
# :only includes matching fragment
|
76
|
+
item[:only].include?(fragment)
|
77
|
+
)
|
78
|
+
) &&
|
80
79
|
(
|
81
|
-
# :except
|
82
|
-
item[:except]
|
83
|
-
# :except
|
84
|
-
|
80
|
+
# :except not defined
|
81
|
+
!item[:except] ||
|
82
|
+
# :except not explicitly named
|
83
|
+
item[:except] != fragment ||
|
84
|
+
(
|
85
|
+
# :except is an array
|
86
|
+
item[:except].respond_to?(:index) &&
|
87
|
+
# :except does not include matching fragment
|
88
|
+
!item[:except].include?(fragment)
|
89
|
+
)
|
85
90
|
)
|
86
91
|
)
|
87
92
|
)
|
88
|
-
|
93
|
+
end
|
89
94
|
end
|
95
|
+
if !cache && self.manual
|
96
|
+
cache = { :path => path, :layout => false }
|
90
97
|
end
|
98
|
+
cache
|
91
99
|
end
|
92
100
|
def self.caches
|
93
|
-
@@caches
|
101
|
+
@@caches if defined?(@@caches)
|
94
102
|
end
|
95
103
|
def self.key
|
96
104
|
Digest::SHA256.hexdigest("--#{Time.now}--#{rand}--")
|
@@ -100,22 +108,7 @@ module BackgroundCache
|
|
100
108
|
end
|
101
109
|
def self.unload!
|
102
110
|
@@caches = []
|
103
|
-
|
104
|
-
# Unique cache id for storing last expired time
|
105
|
-
def self.unique_cache_id(cache)
|
106
|
-
id = []
|
107
|
-
join = lambda do |k, v|
|
108
|
-
id << (k.nil? || v.nil? ?
|
109
|
-
nil : [ k, v ].collect { |kv| kv.to_s.gsub(/\W/, '_') }.join('-')
|
110
|
-
)
|
111
|
-
end
|
112
|
-
cache[:params].each do |key, value|
|
113
|
-
join.call(key, value)
|
114
|
-
end
|
115
|
-
cache.each do |key, value|
|
116
|
-
join.call(key, value) unless key == :params
|
117
|
-
end
|
118
|
-
'background_cache/' + id.compact.join('/')
|
111
|
+
self.manual = nil
|
119
112
|
end
|
120
113
|
end
|
121
114
|
end
|
@@ -19,37 +19,20 @@ module BackgroundCache
|
|
19
19
|
|
20
20
|
class BackgroundCacheFilter
|
21
21
|
def before(controller)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
key = ::ActionController::Base.cache_store.read('background_cache/key')
|
29
|
-
# Turn off the layout if necessary
|
30
|
-
if @background_cache[:key] == key
|
31
|
-
cache = BackgroundCache::Config.from_controller(controller)
|
32
|
-
# Store current layout, then disable it
|
33
|
-
if cache && cache[:layout] == false
|
34
|
-
@background_cache[:layout] = controller.active_layout
|
35
|
-
controller.class.layout(false)
|
36
|
-
end
|
22
|
+
unless BackgroundCache::Config.caches.empty?
|
23
|
+
cache = BackgroundCache::Config.from_controller(controller)
|
24
|
+
# Store current layout, then disable it
|
25
|
+
if cache && cache[:layout] == false
|
26
|
+
@background_cache_layout = controller.active_layout
|
27
|
+
controller.class.layout(false)
|
37
28
|
end
|
38
29
|
end
|
39
30
|
true
|
40
31
|
end
|
41
32
|
def after(controller)
|
42
33
|
# Restore layout
|
43
|
-
if @
|
44
|
-
controller.class.layout(@
|
45
|
-
end
|
46
|
-
if @background_cache[:load]
|
47
|
-
# Secure filters
|
48
|
-
key = ::ActionController::Base.cache_store.read('background_cache/key')
|
49
|
-
# Load the background cache config
|
50
|
-
if @background_cache[:load] == key
|
51
|
-
BackgroundCache::Config.load!
|
52
|
-
end
|
34
|
+
if @background_cache_layout
|
35
|
+
controller.class.layout(@background_cache_layout)
|
53
36
|
end
|
54
37
|
end
|
55
38
|
end
|
@@ -4,21 +4,23 @@ module BackgroundCache
|
|
4
4
|
base.alias_method_chain :cache, :background_cache
|
5
5
|
end
|
6
6
|
def cache_with_background_cache(name = {}, options = nil, &block)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
# http://railsapi.com/doc/rails-v2.3.8/classes/ActionView/Helpers/CacheHelper.html
|
8
|
+
# ActionController::Caching::Fragments#fragment_for (undocumented)
|
9
|
+
# actionpack/lib/action_controller/caching/fragments.rb
|
10
|
+
if @controller.perform_caching
|
11
|
+
if cache = @controller.read_fragment(name, options)
|
12
|
+
output_buffer.concat(cache)
|
13
|
+
else
|
14
|
+
pos = output_buffer.length
|
15
|
+
block.call
|
16
|
+
output = [
|
17
|
+
"<!-- #{name.inspect} cached #{Time.now.strftime("%m/%d/%Y at %I:%M %p")} -->",
|
18
|
+
output_buffer[pos..-1]
|
19
|
+
].join("\n")
|
20
|
+
@controller.write_fragment(name, output, options)
|
21
|
+
end
|
20
22
|
else
|
21
|
-
|
23
|
+
block.call
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
data/lib/background_cache.rb
CHANGED
@@ -12,37 +12,30 @@ module BackgroundCache
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.cache!(group=nil)
|
15
|
-
|
15
|
+
instance = boot
|
16
16
|
caches = BackgroundCache::Config.caches
|
17
17
|
caches.each do |cache|
|
18
18
|
next if group && cache[:group] != group
|
19
19
|
url = cache[:path] || instance.url_for(cache[:params].merge(:only_path => true))
|
20
20
|
puts "(#{cache[:group]}) #{url}"
|
21
|
-
instance.get(url
|
21
|
+
instance.get(url)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.manual(url)
|
26
|
-
|
26
|
+
instance = boot
|
27
|
+
BackgroundCache::Config.manual = true
|
27
28
|
url = instance.url_for(url.merge(:only_path => true)) if url.respond_to?(:keys)
|
28
|
-
instance.get(url
|
29
|
+
instance.get(url)
|
29
30
|
url
|
30
31
|
end
|
31
32
|
|
32
33
|
private
|
33
34
|
|
34
35
|
def self.boot
|
35
|
-
key = set_key!
|
36
36
|
instance = AppInstance.new
|
37
|
-
|
38
|
-
|
39
|
-
[ key, instance ]
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.set_key!
|
43
|
-
key = BackgroundCache::Config.key
|
44
|
-
::ActionController::Base.cache_store.write('background_cache/key', key)
|
45
|
-
key
|
37
|
+
BackgroundCache::Config.load!
|
38
|
+
instance
|
46
39
|
end
|
47
40
|
end
|
48
41
|
|
data/require.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
COMMENT_REGEX = /<!-- ".+" cached .+ -->\n/
|
4
|
-
|
5
3
|
describe BackgroundCache do
|
6
4
|
|
7
5
|
include Rack::Test::Methods
|
@@ -16,23 +14,22 @@ describe BackgroundCache do
|
|
16
14
|
|
17
15
|
describe :Controller do
|
18
16
|
|
19
|
-
it "should call load!
|
20
|
-
key = BackgroundCache.set_key!
|
17
|
+
it "should call load! when cache! called" do
|
21
18
|
BackgroundCache::Config.should_receive(:load!)
|
22
|
-
|
19
|
+
BackgroundCache.cache!
|
23
20
|
end
|
24
21
|
|
25
|
-
it "should call from_controller
|
26
|
-
|
22
|
+
it "should call from_controller when cached request happens" do
|
23
|
+
BackgroundCache.cache!
|
27
24
|
BackgroundCache::Config.should_receive(:from_controller)
|
28
|
-
get('/'
|
25
|
+
get('/')
|
29
26
|
end
|
30
27
|
|
31
28
|
it "should alias read_fragment and return null when it is called on matching cache" do
|
32
|
-
|
33
|
-
get('/'
|
34
|
-
|
35
|
-
get('/t3'
|
29
|
+
BackgroundCache.cache!
|
30
|
+
get('/')
|
31
|
+
cache_write('test_3', 'bust me')
|
32
|
+
get('/t3')
|
36
33
|
last_response.body.should == 'nil'
|
37
34
|
end
|
38
35
|
end
|
@@ -47,21 +44,43 @@ describe BackgroundCache do
|
|
47
44
|
|
48
45
|
it "should be caching normally" do
|
49
46
|
get('/')
|
50
|
-
|
51
|
-
|
47
|
+
cache_read('test').should == 'test'
|
48
|
+
cache_write('test', 'bust me')
|
52
49
|
get('/')
|
53
|
-
|
50
|
+
cache_read('test').should == 'bust me'
|
54
51
|
end
|
55
52
|
|
56
53
|
it "should bust the cache" do
|
57
|
-
|
54
|
+
cache_write('test', 'bust me')
|
58
55
|
BackgroundCache.cache!
|
59
|
-
|
56
|
+
cache_read('test').should == 'test'
|
60
57
|
end
|
61
58
|
|
62
59
|
it "should render the layout" do
|
63
60
|
BackgroundCache.cache!
|
64
|
-
|
61
|
+
cache_read('layout_test_1').should == '1'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe :test_1b do
|
66
|
+
|
67
|
+
it "should be caching normally" do
|
68
|
+
get('/')
|
69
|
+
cache_read('test').should == 'test'
|
70
|
+
cache_write('test', 'bust me')
|
71
|
+
get('/')
|
72
|
+
cache_read('test').should == 'bust me'
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should bust the cache (manual override)" do
|
76
|
+
cache_write('test', 'bust me')
|
77
|
+
BackgroundCache.manual('/b')
|
78
|
+
cache_read('test').should == 'test'
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should not render the layout" do
|
82
|
+
BackgroundCache.manual('/b')
|
83
|
+
cache_read('layout_test_1').should == nil
|
65
84
|
end
|
66
85
|
end
|
67
86
|
|
@@ -69,27 +88,27 @@ describe BackgroundCache do
|
|
69
88
|
|
70
89
|
it "should be caching normally" do
|
71
90
|
get('/t2')
|
72
|
-
|
73
|
-
|
91
|
+
cache_read('test_2').should == 'test 2'
|
92
|
+
cache_write('test_2', 'bust me')
|
74
93
|
get('/t2')
|
75
|
-
|
94
|
+
cache_read('test_2').should == 'bust me'
|
76
95
|
end
|
77
96
|
|
78
97
|
it "should bust the cache" do
|
79
|
-
|
98
|
+
cache_write('test_2', 'bust me')
|
80
99
|
BackgroundCache.cache!
|
81
|
-
|
100
|
+
cache_read('test_2').should == 'test 2'
|
82
101
|
end
|
83
102
|
|
84
103
|
it "should not bust the excluded cache" do
|
85
|
-
|
104
|
+
cache_write('test_1', 'bust me')
|
86
105
|
BackgroundCache.cache!
|
87
|
-
|
106
|
+
cache_read('test_1').should == 'bust me'
|
88
107
|
end
|
89
108
|
|
90
109
|
it "should not render the layout" do
|
91
110
|
BackgroundCache.cache!
|
92
|
-
|
111
|
+
cache_read('layout_test_2').should == nil
|
93
112
|
end
|
94
113
|
end
|
95
114
|
end
|
@@ -43,6 +43,7 @@ ActionController::Routing::Routes.draw do |map|
|
|
43
43
|
#map.connect ':controller/:action/:id.:format'
|
44
44
|
|
45
45
|
map.connect '/', :controller => 'application', :action => 'test_1'
|
46
|
+
map.connect '/b', :controller => 'application', :action => 'test_1'
|
46
47
|
map.connect '/t2', :controller => 'application', :action => 'test_2'
|
47
48
|
map.connect '/t3', :controller => 'application', :action => 'test_3'
|
48
49
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,3 +5,14 @@ Require.spec_helper!
|
|
5
5
|
|
6
6
|
Spec::Runner.configure do |config|
|
7
7
|
end
|
8
|
+
|
9
|
+
COMMENT_REGEX = /<!-- ".+" cached .+ -->\n/
|
10
|
+
|
11
|
+
def cache_read(key)
|
12
|
+
value = ::ActionController::Base.cache_store.read('views/' + key)
|
13
|
+
value ? value.gsub(COMMENT_REGEX, '') : value
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_write(key, value)
|
17
|
+
::ActionController::Base.cache_store.write('views/' + key, value)
|
18
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: background_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Winton Welsh
|
@@ -9,29 +15,41 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-09-14 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: rack-test
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - "="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 5
|
33
|
+
- 3
|
23
34
|
version: 0.5.3
|
24
|
-
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: require
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
43
|
- - "="
|
32
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 25
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 2
|
49
|
+
- 7
|
33
50
|
version: 0.2.7
|
34
|
-
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
35
53
|
description:
|
36
54
|
email: mail@wintoni.us
|
37
55
|
executables: []
|
@@ -82,21 +100,27 @@ rdoc_options: []
|
|
82
100
|
require_paths:
|
83
101
|
- lib
|
84
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
85
104
|
requirements:
|
86
105
|
- - ">="
|
87
106
|
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
88
110
|
version: "0"
|
89
|
-
version:
|
90
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
91
113
|
requirements:
|
92
114
|
- - ">="
|
93
115
|
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
94
119
|
version: "0"
|
95
|
-
version:
|
96
120
|
requirements: []
|
97
121
|
|
98
122
|
rubyforge_project:
|
99
|
-
rubygems_version: 1.3.
|
123
|
+
rubygems_version: 1.3.7
|
100
124
|
signing_key:
|
101
125
|
specification_version: 3
|
102
126
|
summary: Bust caches before your users do
|