lacquer 0.4.1 → 0.5.0.beta1
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/Gemfile +7 -3
- data/README.rdoc +118 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/init.rb +1 -1
- data/lacquer.gemspec +32 -21
- data/lib/generators/lacquer/install_generator.rb +5 -1
- data/lib/generators/lacquer/templates/{varnish.sample.vcl → varnish.vcl.erb} +27 -27
- data/lib/generators/lacquer/templates/varnishd.yml +26 -0
- data/lib/lacquer/cache_control.rb +61 -0
- data/lib/lacquer/cache_utils.rb +9 -11
- data/lib/lacquer/capistrano.rb +20 -0
- data/lib/lacquer/delayed_job_job.rb +2 -2
- data/lib/lacquer/railtie.rb +9 -0
- data/lib/lacquer/recipes.rb +62 -0
- data/lib/lacquer/resque_job.rb +2 -2
- data/lib/lacquer/tasks.rb +37 -0
- data/lib/lacquer/varnish.rb +7 -5
- data/lib/lacquer/varnishd.rb +131 -0
- data/lib/lacquer.rb +4 -0
- data/rails/init.rb +1 -1
- data/recipes/lacquer.rb +1 -0
- data/spec/config/generate.vcl.erb +16 -0
- data/spec/config/varnish.vcl +16 -0
- data/spec/config/varnishd.yml +10 -0
- data/spec/lacquer/cache_control_spec.rb +72 -0
- data/spec/lacquer/cache_utils_spec.rb +5 -4
- data/spec/lacquer/varnishd_spec.rb +71 -0
- data/tasks/lacquer.rake +1 -0
- metadata +51 -83
- data/Gemfile.lock +0 -34
data/Gemfile
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
gem "activesupport", "3.0
|
4
|
-
gem "i18n", "0.4
|
3
|
+
gem "activesupport", "~> 3.0"
|
4
|
+
gem "i18n", "~> 0.4"
|
5
5
|
gem "jeweler"
|
6
6
|
gem "rake"
|
7
|
-
gem "rspec", "2.0.0"
|
8
7
|
gem "yard"
|
8
|
+
gem "erubis"
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem "rspec", "~> 2.5", :require => false
|
12
|
+
end
|
data/README.rdoc
CHANGED
@@ -5,7 +5,8 @@ Rails drop in for Varnish support.
|
|
5
5
|
== Install
|
6
6
|
Basic installation
|
7
7
|
|
8
|
-
sudo gem install lacquer
|
8
|
+
sudo gem install lacquer
|
9
|
+
rails generate lacquer:install
|
9
10
|
|
10
11
|
config/initializers/lacquer.rb
|
11
12
|
|
@@ -36,7 +37,115 @@ app/controllers/application_controller.rb
|
|
36
37
|
class ApplicationController < ActionController::Base
|
37
38
|
include Lacquer::CacheUtils
|
38
39
|
end
|
40
|
+
|
41
|
+
config/varnishd.yml
|
42
|
+
|
43
|
+
development:
|
44
|
+
listen: localhost:3001
|
45
|
+
telnet: localhost:6082
|
46
|
+
sbin_path: /usr/local/sbin
|
47
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
48
|
+
|
49
|
+
test:
|
50
|
+
listen: localhost:3002
|
51
|
+
telnet: localhost:6083
|
52
|
+
sbin_path: /usr/local/sbin
|
53
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
54
|
+
|
55
|
+
production:
|
56
|
+
listen: :80
|
57
|
+
telnet: localhost:6082
|
58
|
+
sbin_path: /usr/local/sbin
|
59
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
60
|
+
params:
|
61
|
+
overflow_max: 2000
|
62
|
+
thread_pool_add_delay: 2
|
63
|
+
thread_pools: 4 # <Number of cpu cores>
|
64
|
+
thread_pool_min: 200 # <800/number of cpu cores>
|
65
|
+
thread_pool_max: 4000
|
66
|
+
|
67
|
+
If only some urls of the application should be cached by varnish, Lacquer::CacheControl will be helpful.
|
68
|
+
|
69
|
+
config/initializers/caches.rb
|
70
|
+
|
71
|
+
require "lacquer/cache_control"
|
72
|
+
|
73
|
+
Lacquer.cache_control.configure do |config|
|
74
|
+
config.register :static, :url => "^/images",
|
75
|
+
:expires_in => "365d"
|
76
|
+
|
77
|
+
config.register :static, :url => "^/stylesheets",
|
78
|
+
:expires_in => "365d"
|
79
|
+
|
80
|
+
config.register :static, :url => "^/javascripts",
|
81
|
+
:expires_in => "365d"
|
82
|
+
|
83
|
+
config.register :class_section, :url => "^(/[a-z]{2})?/(info_screens|class_sections)/%s.*$",
|
84
|
+
:args => "[0-9]+",
|
85
|
+
:expires_in => "1m"
|
86
|
+
|
87
|
+
config.register :open_scoring, :url => "^(/[a-z]{2})?/class_sections/%s/open_scoring.*$",
|
88
|
+
:args => "[0-9]+",
|
89
|
+
:expires_in => "1m"
|
90
|
+
|
91
|
+
end
|
39
92
|
|
93
|
+
In the sweeper we can do something like this
|
94
|
+
|
95
|
+
class_section = ClassSection.find(1)
|
96
|
+
Lacquer.cache_control.purge(:open_scoring, class_section)
|
97
|
+
|
98
|
+
This will purge "^(/[a-z]{2})?/class_sections/1/open_scoring.*$" (/sv/class_sections/1/open_scoring.js, /sv/class_sections/1/open_scoring.html)
|
99
|
+
|
100
|
+
The varnish.vcl is preprocssed when starting varnishd with the rake tasks
|
101
|
+
|
102
|
+
rake varnishd:start
|
103
|
+
|
104
|
+
config/varnish.vcl.erb
|
105
|
+
|
106
|
+
sub vcl_recv {
|
107
|
+
# Lookup requests that we know should be cached
|
108
|
+
if (<%= Lacquer.cache_control.to_vcl_conditions %>) {
|
109
|
+
# Clear cookie and authorization headers, set grace time, lookup in the cache
|
110
|
+
unset req.http.Cookie;
|
111
|
+
unset req.http.Authorization;
|
112
|
+
return(lookup);
|
113
|
+
}
|
114
|
+
|
115
|
+
# Generates
|
116
|
+
#
|
117
|
+
# if(req.url ~ "^/images" ||
|
118
|
+
# req.url ~ "^/stylesheets" ||
|
119
|
+
# req.url ~ "^/javascripts" ||
|
120
|
+
# req.url ~ "^(/[a-z]{2})?/(info_screens|class_sections)/[0-9]+.*$" ||
|
121
|
+
# req.url ~ "^(/[a-z]{2})?/class_sections/[0-9]+/open_scoring.*$") {
|
122
|
+
# unset req.http.Cookie;
|
123
|
+
# unset req.http.Authorization;
|
124
|
+
# return(lookup);
|
125
|
+
# }
|
126
|
+
}
|
127
|
+
|
128
|
+
sub vcl_fetch {
|
129
|
+
<%= Lacquer.cache_control.to_vcl_override_ttl_urls %>
|
130
|
+
|
131
|
+
# Generates
|
132
|
+
#
|
133
|
+
# if(req.url ~ "^/images" || req.url ~ "^/stylesheets" || req.url ~ "^/javascripts") {
|
134
|
+
# unset beresp.http.Set-Cookie;
|
135
|
+
# set beresp.ttl = 365d;
|
136
|
+
# return(deliver);
|
137
|
+
# }
|
138
|
+
#
|
139
|
+
# if(req.url ~ "^(/[a-z]{2})?/(info_screens|class_sections)/[0-9]+.*$" ||
|
140
|
+
# req.url ~ "^(/[a-z]{2})?/class_sections/[0-9]+/open_scoring.*$") {
|
141
|
+
# unset beresp.http.Set-Cookie;
|
142
|
+
# set beresp.ttl = 1m;
|
143
|
+
# return(deliver);
|
144
|
+
# }
|
145
|
+
}
|
146
|
+
|
147
|
+
This makes it much simpler to perform cacheing, it's only setuped in one place, purge it or just let it expire.
|
148
|
+
|
40
149
|
== Usage
|
41
150
|
|
42
151
|
To set a custom ttl for a controller:
|
@@ -57,6 +166,14 @@ Clearing the cache:
|
|
57
166
|
post_path(@post))
|
58
167
|
end
|
59
168
|
end
|
169
|
+
|
170
|
+
Control varnishd with the following rake tasks
|
171
|
+
|
172
|
+
rake varnishd:start
|
173
|
+
rake varnishd:stop
|
174
|
+
rake varnishd:restart
|
175
|
+
rake varnishd:status
|
176
|
+
rake varnishd:global_purge
|
60
177
|
|
61
178
|
== Gotchas
|
62
179
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require "rubygems"
|
2
3
|
require "bundler/setup"
|
3
4
|
|
@@ -14,8 +15,7 @@ begin
|
|
14
15
|
gem.description = %Q{Rails drop in for Varnish support.}
|
15
16
|
gem.email = "russ@bashme.org"
|
16
17
|
gem.homepage = "http://github.com/russ/lacquer"
|
17
|
-
gem.authors = ["Russ Smith (russ@bashme.org)", "Ryan Johns", "Garry Tan (garry@posterous.com), Gabe da Silveira (gabe@websaviour.com)"]
|
18
|
-
gem.add_development_dependency "rspec", "~> 1.3.0"
|
18
|
+
gem.authors = ["Russ Smith (russ@bashme.org)", "Ryan Johns", "Garry Tan (garry@posterous.com), Gabe da Silveira (gabe@websaviour.com)", "Håkon Lerring"]
|
19
19
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
20
|
end
|
21
21
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0.beta1
|
data/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'lib', 'lacquer')
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib', 'lacquer')
|
data/lacquer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lacquer}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0.beta1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
11
|
-
s.authors = ["Russ Smith (russ@bashme.org)", "Ryan Johns", "Garry Tan (garry@posterous.com), Gabe da Silveira (gabe@websaviour.com)"]
|
12
|
-
s.date = %q{
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Russ Smith (russ@bashme.org)", "Ryan Johns", "Garry Tan (garry@posterous.com), Gabe da Silveira (gabe@websaviour.com)", "Håkon Lerring"]
|
12
|
+
s.date = %q{2011-04-25}
|
13
13
|
s.description = %q{Rails drop in for Varnish support.}
|
14
14
|
s.email = %q{russ@bashme.org}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
".bundle/config",
|
21
21
|
".document",
|
22
22
|
"Gemfile",
|
23
|
-
"Gemfile.lock",
|
24
23
|
"LICENSE",
|
25
24
|
"README.rdoc",
|
26
25
|
"Rakefile",
|
@@ -30,61 +29,73 @@ Gem::Specification.new do |s|
|
|
30
29
|
"lib/generators/lacquer/USAGE",
|
31
30
|
"lib/generators/lacquer/install_generator.rb",
|
32
31
|
"lib/generators/lacquer/templates/initializer.rb",
|
33
|
-
"lib/generators/lacquer/templates/varnish.
|
32
|
+
"lib/generators/lacquer/templates/varnish.vcl.erb",
|
33
|
+
"lib/generators/lacquer/templates/varnishd.yml",
|
34
34
|
"lib/lacquer.rb",
|
35
|
+
"lib/lacquer/cache_control.rb",
|
35
36
|
"lib/lacquer/cache_utils.rb",
|
37
|
+
"lib/lacquer/capistrano.rb",
|
36
38
|
"lib/lacquer/configuration.rb",
|
37
39
|
"lib/lacquer/delayed_job_job.rb",
|
40
|
+
"lib/lacquer/railtie.rb",
|
41
|
+
"lib/lacquer/recipes.rb",
|
38
42
|
"lib/lacquer/resque_job.rb",
|
43
|
+
"lib/lacquer/tasks.rb",
|
39
44
|
"lib/lacquer/varnish.rb",
|
45
|
+
"lib/lacquer/varnishd.rb",
|
40
46
|
"rails/init.rb",
|
47
|
+
"recipes/lacquer.rb",
|
48
|
+
"spec/config/generate.vcl.erb",
|
49
|
+
"spec/config/varnish.vcl",
|
50
|
+
"spec/config/varnishd.yml",
|
51
|
+
"spec/lacquer/cache_control_spec.rb",
|
41
52
|
"spec/lacquer/cache_utils_spec.rb",
|
42
53
|
"spec/lacquer/delayed_job_job_spec.rb",
|
43
54
|
"spec/lacquer/resque_job_spec.rb",
|
44
55
|
"spec/lacquer/varnish_spec.rb",
|
45
|
-
"spec/
|
56
|
+
"spec/lacquer/varnishd_spec.rb",
|
57
|
+
"spec/spec_helper.rb",
|
58
|
+
"tasks/lacquer.rake"
|
46
59
|
]
|
47
60
|
s.homepage = %q{http://github.com/russ/lacquer}
|
48
61
|
s.require_paths = ["lib"]
|
49
|
-
s.rubygems_version = %q{1.
|
62
|
+
s.rubygems_version = %q{1.5.0}
|
50
63
|
s.summary = %q{Rails drop in for Varnish support.}
|
51
64
|
s.test_files = [
|
65
|
+
"spec/lacquer/cache_control_spec.rb",
|
52
66
|
"spec/lacquer/cache_utils_spec.rb",
|
53
67
|
"spec/lacquer/delayed_job_job_spec.rb",
|
54
68
|
"spec/lacquer/resque_job_spec.rb",
|
55
69
|
"spec/lacquer/varnish_spec.rb",
|
70
|
+
"spec/lacquer/varnishd_spec.rb",
|
56
71
|
"spec/spec_helper.rb"
|
57
72
|
]
|
58
73
|
|
59
74
|
if s.respond_to? :specification_version then
|
60
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
61
75
|
s.specification_version = 3
|
62
76
|
|
63
77
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
65
|
-
s.add_runtime_dependency(%q<i18n>, ["
|
78
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0"])
|
79
|
+
s.add_runtime_dependency(%q<i18n>, ["~> 0.4"])
|
66
80
|
s.add_runtime_dependency(%q<jeweler>, [">= 0"])
|
67
81
|
s.add_runtime_dependency(%q<rake>, [">= 0"])
|
68
|
-
s.add_runtime_dependency(%q<rspec>, ["= 2.0.0"])
|
69
82
|
s.add_runtime_dependency(%q<yard>, [">= 0"])
|
70
|
-
s.
|
83
|
+
s.add_runtime_dependency(%q<erubis>, [">= 0"])
|
71
84
|
else
|
72
|
-
s.add_dependency(%q<activesupport>, ["
|
73
|
-
s.add_dependency(%q<i18n>, ["
|
85
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0"])
|
86
|
+
s.add_dependency(%q<i18n>, ["~> 0.4"])
|
74
87
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
75
88
|
s.add_dependency(%q<rake>, [">= 0"])
|
76
|
-
s.add_dependency(%q<rspec>, ["= 2.0.0"])
|
77
89
|
s.add_dependency(%q<yard>, [">= 0"])
|
78
|
-
s.add_dependency(%q<
|
90
|
+
s.add_dependency(%q<erubis>, [">= 0"])
|
79
91
|
end
|
80
92
|
else
|
81
|
-
s.add_dependency(%q<activesupport>, ["
|
82
|
-
s.add_dependency(%q<i18n>, ["
|
93
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0"])
|
94
|
+
s.add_dependency(%q<i18n>, ["~> 0.4"])
|
83
95
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
84
96
|
s.add_dependency(%q<rake>, [">= 0"])
|
85
|
-
s.add_dependency(%q<rspec>, ["= 2.0.0"])
|
86
97
|
s.add_dependency(%q<yard>, [">= 0"])
|
87
|
-
s.add_dependency(%q<
|
98
|
+
s.add_dependency(%q<erubis>, [">= 0"])
|
88
99
|
end
|
89
100
|
end
|
90
101
|
|
@@ -8,7 +8,11 @@ module Lacquer
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def copy_vcl
|
11
|
-
copy_file("varnish.
|
11
|
+
copy_file("varnish.vcl.erb", "config/varnish.vcl.erb")
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_varnishd_config
|
15
|
+
copy_file("varnishd.yml", "config/varnishd.yml")
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
backend default {
|
2
|
-
.host = "
|
3
|
-
.port = "
|
2
|
+
.host = "<%= backend.split(':').first %>";
|
3
|
+
.port = "<%= backend.split(':').last %>";
|
4
4
|
}
|
5
5
|
|
6
6
|
# Handling of requests that are received from clients.
|
@@ -14,19 +14,20 @@ sub vcl_recv {
|
|
14
14
|
req.request != "TRACE" &&
|
15
15
|
req.request != "OPTIONS" &&
|
16
16
|
req.request != "DELETE") {
|
17
|
-
pipe;
|
17
|
+
return(pipe);
|
18
18
|
}
|
19
|
-
|
19
|
+
|
20
|
+
if (req.backend.healthy) {
|
21
|
+
set req.grace = 30s;
|
22
|
+
} else {
|
23
|
+
set req.grace = 1h;
|
24
|
+
}
|
25
|
+
|
20
26
|
# Pass requests that are not GET or HEAD
|
21
27
|
if (req.request != "GET" && req.request != "HEAD") {
|
22
|
-
pass;
|
23
|
-
}
|
24
|
-
|
25
|
-
# Pass requests that we know we aren't caching
|
26
|
-
if (req.url ~ "^/admin") {
|
27
|
-
pass;
|
28
|
+
return(pass);
|
28
29
|
}
|
29
|
-
|
30
|
+
|
30
31
|
# Handle compression correctly. Varnish treats headers literally, not
|
31
32
|
# semantically. So it is very well possible that there are cache misses
|
32
33
|
# because the headers sent by different browsers aren't the same.
|
@@ -47,8 +48,7 @@ sub vcl_recv {
|
|
47
48
|
# Clear cookie and authorization headers, set grace time, lookup in the cache
|
48
49
|
unset req.http.Cookie;
|
49
50
|
unset req.http.Authorization;
|
50
|
-
|
51
|
-
lookup;
|
51
|
+
return(lookup);
|
52
52
|
}
|
53
53
|
|
54
54
|
# Called when entering pipe mode
|
@@ -57,34 +57,34 @@ sub vcl_pipe {
|
|
57
57
|
# requests from the client will also be piped through and
|
58
58
|
# left untouched by varnish. We don't want that.
|
59
59
|
set req.http.connection = "close";
|
60
|
-
pipe;
|
60
|
+
return(pipe);
|
61
61
|
}
|
62
62
|
|
63
63
|
# Called when the requested object has been retrieved from the
|
64
64
|
# backend, or the request to the backend has failed
|
65
65
|
sub vcl_fetch {
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
}
|
70
|
-
|
66
|
+
# Set the grace time
|
67
|
+
set beresp.grace = 1h;
|
68
|
+
|
71
69
|
# Do not cache the object if the status is not in the 200s
|
72
|
-
if (
|
70
|
+
if (beresp.status >= 300) {
|
73
71
|
# Remove the Set-Cookie header
|
74
|
-
remove
|
75
|
-
pass;
|
72
|
+
remove beresp.http.Set-Cookie;
|
73
|
+
return(pass);
|
74
|
+
}
|
75
|
+
|
76
|
+
# Do not cache the object if the backend application does not want us to.
|
77
|
+
if (beresp.http.Cache-Control ~ "(no-cache|no-store|private|must-revalidate)") {
|
78
|
+
return(pass);
|
76
79
|
}
|
77
80
|
|
78
81
|
# Everything below here should be cached
|
79
82
|
|
80
83
|
# Remove the Set-Cookie header
|
81
|
-
remove
|
82
|
-
|
83
|
-
# Set the grace time
|
84
|
-
set obj.grace = 30s;
|
84
|
+
remove beresp.http.Set-Cookie;
|
85
85
|
|
86
86
|
# Deliver the object
|
87
|
-
deliver;
|
87
|
+
return(deliver);
|
88
88
|
}
|
89
89
|
|
90
90
|
# Called before the response is sent back to the client
|
@@ -0,0 +1,26 @@
|
|
1
|
+
development:
|
2
|
+
listen: 127.0.0.1:3001
|
3
|
+
telnet: 127.0.0.1:6082
|
4
|
+
backend: 127.0.0.1:3000
|
5
|
+
sbin_path: /usr/local/sbin
|
6
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
7
|
+
|
8
|
+
test:
|
9
|
+
listen: 127.0.0.1:3002
|
10
|
+
telnet: 127.0.0.1:6083
|
11
|
+
backend: 127.0.0.1:3000
|
12
|
+
sbin_path: /usr/local/sbin
|
13
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
14
|
+
|
15
|
+
production:
|
16
|
+
listen: :80
|
17
|
+
telnet: localhost:6082
|
18
|
+
backend: backend_server:8080
|
19
|
+
sbin_path: /usr/local/sbin
|
20
|
+
storage: "file,#{Rails.root}/log/varnishd.#{Rails.env}.cache,100MB"
|
21
|
+
params:
|
22
|
+
overflow_max: 2000
|
23
|
+
thread_pool_add_delay: 2
|
24
|
+
thread_pools: 4 # <Number of cpu cores>
|
25
|
+
thread_pool_min: 200 # <800/number of cpu cores>
|
26
|
+
thread_pool_max: 4000
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Lacquer
|
2
|
+
|
3
|
+
def self.cache_control
|
4
|
+
@cache_control ||= CacheControl.new
|
5
|
+
end
|
6
|
+
|
7
|
+
class CacheControl
|
8
|
+
include Lacquer::CacheUtils
|
9
|
+
attr_accessor :store
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
self.store = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(group, options = {})
|
16
|
+
options[:group] = group
|
17
|
+
options[:args] = Array(options[:args]).compact
|
18
|
+
store << options
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
|
25
|
+
def purge(group, *args)
|
26
|
+
clear_cache_for(*urls_for(group, *args))
|
27
|
+
end
|
28
|
+
|
29
|
+
def urls_for(group, *args)
|
30
|
+
args.map! { |arg| arg.to_param }
|
31
|
+
urls_by(group).map { |options| options[:url] % args }
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_vcl_conditions(urls = store)
|
35
|
+
urls.map { |opt| %Q[req.url ~ "#{(opt[:url] % opt[:args])}"] }.join(" || ")
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_vcl_override_ttl_urls
|
39
|
+
urls_grouped_by_expires.map do |expires_in, list|
|
40
|
+
<<-CODE.strip_heredoc
|
41
|
+
if(#{to_vcl_conditions(list)}) {
|
42
|
+
unset beresp.http.Set-Cookie;
|
43
|
+
set beresp.ttl = #{expires_in};
|
44
|
+
return(deliver);
|
45
|
+
}
|
46
|
+
CODE
|
47
|
+
end.join("\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def urls_grouped_by_expires
|
53
|
+
store.group_by { |opt| opt[:expires_in] }.select { |expires_in, list| expires_in }
|
54
|
+
end
|
55
|
+
|
56
|
+
def urls_by(group)
|
57
|
+
store.select { |opt| opt[:group] == group }
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
data/lib/lacquer/cache_utils.rb
CHANGED
@@ -26,17 +26,15 @@ module Lacquer
|
|
26
26
|
#
|
27
27
|
# clear_cache_for(root_path, blog_posts_path, '/other/content/*')
|
28
28
|
def clear_cache_for(*paths)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
Varnish.new.purge(path)
|
39
|
-
end
|
29
|
+
case Lacquer.configuration.job_backend
|
30
|
+
when :delayed_job
|
31
|
+
require 'lacquer/delayed_job_job'
|
32
|
+
Delayed::Job.enqueue(Lacquer::DelayedJobJob.new(paths))
|
33
|
+
when :resque
|
34
|
+
require 'lacquer/resque_job'
|
35
|
+
Resque.enqueue(Lacquer::ResqueJob, paths)
|
36
|
+
when :none
|
37
|
+
Varnish.new.purge(*paths)
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Capistrano tasks for Lacquer
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exit).load do
|
4
|
+
_cset(:lacquer_roles) { :web }
|
5
|
+
|
6
|
+
after "deploy:web:disable", "lacquer:global_purge"
|
7
|
+
after "deploy:web:enable", "lacquer:global_purge"
|
8
|
+
after "deploy:rollback", "lacquer:global_purge"
|
9
|
+
after "deploy:rollback", "lacquer:restart"
|
10
|
+
after "deploy:update", "lacquer:restart"
|
11
|
+
|
12
|
+
namespace :lacquer do
|
13
|
+
%w( start stop restart global_purge status ).each do |name|
|
14
|
+
task name.to_sym, :roles => lacquer_roles do
|
15
|
+
next if find_servers_for_task(current_task).empty?
|
16
|
+
run "cd #{current_path} && #{rake} varnishd:#{name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Capistrano Recipes for managing varnishd
|
2
|
+
#
|
3
|
+
# Add these callbacks to have the varnishd process restart when the server
|
4
|
+
# is restarted:
|
5
|
+
#
|
6
|
+
# after "deploy:stop", "delayed_job:stop"
|
7
|
+
# after "deploy:start", "delayed_job:start"
|
8
|
+
# after "deploy:restart", "delayed_job:restart"
|
9
|
+
#
|
10
|
+
# If you've got varnishd running on a servers, you can also specify
|
11
|
+
# which servers have varnishd running and should be restarted after deploy.
|
12
|
+
#
|
13
|
+
# set :varnishd_role, :varnish
|
14
|
+
#
|
15
|
+
|
16
|
+
Capistrano::Configuration.instance.load do
|
17
|
+
namespace :varnishd do
|
18
|
+
def rails_env
|
19
|
+
fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''
|
20
|
+
end
|
21
|
+
|
22
|
+
def rake
|
23
|
+
fetch(:rake, 'rake')
|
24
|
+
end
|
25
|
+
|
26
|
+
def roles
|
27
|
+
fetch(:varnishd_role, :varnish)
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Link varnishd.yml from shared/config to app/config"
|
31
|
+
task :link_varnishd_yml, :roles => lambda { roles } do
|
32
|
+
run "cd #{release_path} && ln -nfs #{shared_path}/config/varnishd.yml #{release_path}/config/varnishd.yml"
|
33
|
+
end
|
34
|
+
after 'deploy:update_code', 'varnishd:link_varnishd_yml'
|
35
|
+
|
36
|
+
desc "Link varnish.vcl from shared/config to app/config"
|
37
|
+
task :link_varnish_vcl, :roles => lambda { roles } do
|
38
|
+
run "cd #{release_path} && ln -nfs #{shared_path}/config/varnish.vcl #{release_path}/config/varnish.vcl"
|
39
|
+
end
|
40
|
+
after 'deploy:update_code', 'varnishd:link_varnishd_vcl'
|
41
|
+
|
42
|
+
desc "Purge ALL urls from Varnish"
|
43
|
+
task :global_purge, :roles => lambda { roles } do
|
44
|
+
run "cd #{current_path};#{rails_env} #{rake} varnishd:global_purge"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Stop the varnishd process"
|
48
|
+
task :stop, :roles => lambda { roles } do
|
49
|
+
run "cd #{current_path};#{rails_env} #{rake} varnishd:stop"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Start the varnishd process"
|
53
|
+
task :start, :roles => lambda { roles } do
|
54
|
+
run "cd #{current_path};#{rails_env} #{rake} varnishd:start"
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Restart the delayed_job process"
|
58
|
+
task :restart, :roles => lambda { roles } do
|
59
|
+
run "cd #{current_path};#{rails_env} #{rake} varnishd:restart"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/lacquer/resque_job.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
namespace :varnishd do
|
2
|
+
|
3
|
+
desc "Start varnishd daemon using Lacquer's settings"
|
4
|
+
task :start => :environment do
|
5
|
+
Lacquer::Varnishd.new.start
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Stop varnishd daemon using Lacquer's settings"
|
9
|
+
task :stop => :environment do
|
10
|
+
Lacquer::Varnishd.new.stop
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Running status of varnishd daemon using Lacquer's settings"
|
14
|
+
task :status => :environment do
|
15
|
+
if Lacquer::Varnishd.new.running?
|
16
|
+
puts "Varnishd is running"
|
17
|
+
else
|
18
|
+
puts "Varnishd is not running"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Restart varnishd daemon using Lacquer's settings"
|
23
|
+
task :restart => :environment do
|
24
|
+
varnishd = Lacquer::Varnishd.new
|
25
|
+
if varnishd.running?
|
26
|
+
varnishd.stop
|
27
|
+
sleep(1)
|
28
|
+
end
|
29
|
+
varnishd.start
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Purge ALL urls from Varnish"
|
33
|
+
task :global_purge => :environment do
|
34
|
+
Lacquer::Varnish.new.purge('.*')
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|