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.
@@ -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
- if defined?(@@caches) && !@@caches.empty?
53
- @@caches.detect do |item|
54
- # Basic params match (action, controller, etc)
55
- (
56
- (item[:path] && item[:path] == path) ||
57
- item[:params] == params.symbolize_keys
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 is an array
70
- item[:only].respond_to?(:index) &&
71
- # :only includes matching fragment
72
- item[:only].include?(fragment)
73
- )
74
- ) &&
75
- (
76
- # :except not defined
77
- !item[:except] ||
78
- # :except not explicitly named
79
- item[:except] != fragment ||
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 is an array
82
- item[:except].respond_to?(:index) &&
83
- # :except does not include matching fragment
84
- !item[:except].include?(fragment)
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
- end
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
- @background_cache = {
23
- :key => controller.params.delete("background_cache"),
24
- :load => controller.params.delete("background_cache_load")
25
- }
26
- if @background_cache[:key]
27
- # Secure filters
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 @background_cache[:layout]
44
- controller.class.layout(@background_cache[: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
- cache = BackgroundCache::Config.from_controller_and_fragment(controller, name)
8
- if cache
9
- RAILS_DEFAULT_LOGGER.info "Cached fragment busted (cache block): #{name.inspect}"
10
- # http://api.rubyonrails.org/classes/ActionView/Helpers/CacheHelper.html
11
- # http://api.rubyonrails.org/classes/ActionController/Caching/Fragments.html
12
- # ActionController::Caching::Fragments#fragment_for (undocumented)
13
- pos = output_buffer.length
14
- block.call
15
- output = [
16
- "<!-- #{name.inspect} cached #{Time.now.strftime("%m/%d/%Y at %I:%M %p")} -->",
17
- output_buffer[pos..-1]
18
- ].join("\n")
19
- @controller.write_fragment(name, output, options)
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
- cache_without_background_cache(name, options, &block)
23
+ block.call
22
24
  end
23
25
  end
24
26
  end
@@ -12,37 +12,30 @@ module BackgroundCache
12
12
  end
13
13
 
14
14
  def self.cache!(group=nil)
15
- key, instance = boot
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 + "#{url.include?('?') ? '&' : '?'}background_cache=#{key}")
21
+ instance.get(url)
22
22
  end
23
23
  end
24
24
 
25
25
  def self.manual(url)
26
- key, instance = boot
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 + "#{url.include?('?') ? '&' : '?'}background_cache=#{key}")
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
- instance.get("/?background_cache_load=#{key}")
38
- load RAILS_ROOT + "/lib/background_cache_config.rb"
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
@@ -18,7 +18,7 @@ Require do
18
18
  name 'background_cache'
19
19
  homepage "http://github.com/winton/#{name}"
20
20
  summary "Bust caches before your users do"
21
- version '0.1.1'
21
+ version '0.1.2'
22
22
  end
23
23
 
24
24
  bin { require 'lib/background_cache' }
@@ -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! with background_cache_load parameter" do
20
- key = BackgroundCache.set_key!
17
+ it "should call load! when cache! called" do
21
18
  BackgroundCache::Config.should_receive(:load!)
22
- get('/', { :background_cache_load => key })
19
+ BackgroundCache.cache!
23
20
  end
24
21
 
25
- it "should call from_controller with background_cache parameter" do
26
- key = BackgroundCache.set_key!
22
+ it "should call from_controller when cached request happens" do
23
+ BackgroundCache.cache!
27
24
  BackgroundCache::Config.should_receive(:from_controller)
28
- get('/', { :background_cache => key })
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
- key = BackgroundCache.set_key!
33
- get('/', { :background_cache_load => key })
34
- ::ActionController::Base.cache_store.write('views/test_3', 'bust me')
35
- get('/t3', { :background_cache => key })
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
- ::ActionController::Base.cache_store.read('views/test').should == 'test'
51
- ::ActionController::Base.cache_store.write('views/test', 'bust me')
47
+ cache_read('test').should == 'test'
48
+ cache_write('test', 'bust me')
52
49
  get('/')
53
- ::ActionController::Base.cache_store.read('views/test').should == 'bust me'
50
+ cache_read('test').should == 'bust me'
54
51
  end
55
52
 
56
53
  it "should bust the cache" do
57
- ::ActionController::Base.cache_store.write('views/test', 'bust me')
54
+ cache_write('test', 'bust me')
58
55
  BackgroundCache.cache!
59
- ::ActionController::Base.cache_store.read('views/test').gsub(COMMENT_REGEX, '').should == 'test'
56
+ cache_read('test').should == 'test'
60
57
  end
61
58
 
62
59
  it "should render the layout" do
63
60
  BackgroundCache.cache!
64
- ::ActionController::Base.cache_store.read('views/layout_test_1').gsub(COMMENT_REGEX, '').should == '1'
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
- ::ActionController::Base.cache_store.read('views/test_2').should == 'test 2'
73
- ::ActionController::Base.cache_store.write('views/test_2', 'bust me')
91
+ cache_read('test_2').should == 'test 2'
92
+ cache_write('test_2', 'bust me')
74
93
  get('/t2')
75
- ::ActionController::Base.cache_store.read('views/test_2').should == 'bust me'
94
+ cache_read('test_2').should == 'bust me'
76
95
  end
77
96
 
78
97
  it "should bust the cache" do
79
- ::ActionController::Base.cache_store.write('views/test_2', 'bust me')
98
+ cache_write('test_2', 'bust me')
80
99
  BackgroundCache.cache!
81
- ::ActionController::Base.cache_store.read('views/test_2').gsub(COMMENT_REGEX, '').should == 'test 2'
100
+ cache_read('test_2').should == 'test 2'
82
101
  end
83
102
 
84
103
  it "should not bust the excluded cache" do
85
- ::ActionController::Base.cache_store.write('views/test_1', 'bust me')
104
+ cache_write('test_1', 'bust me')
86
105
  BackgroundCache.cache!
87
- ::ActionController::Base.cache_store.read('views/test_1').should == 'bust me'
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
- ::ActionController::Base.cache_store.read('views/layout_test_2').should == nil
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
- version: 0.1.1
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-06-16 00:00:00 -07:00
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
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: require
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
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.5
123
+ rubygems_version: 1.3.7
100
124
  signing_key:
101
125
  specification_version: 3
102
126
  summary: Bust caches before your users do