lacquer 0.4.1 → 0.5.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|