Gary Weaver
2012-Dec-18 20:57 UTC
cache-busting non-digest assets in sprockets in development a good idea? should headers in sprockets be configurable?
Just monkey patched Sprockets in our Rails 3.2.9 app to override the
Cache-Control header for html assets that we need to tweak more often in
development, but that we don''t want to use digests/fingerprinting with:
# Sprockets 2.x patch
if Rails.env.development?
module Sprockets
module Server
private
alias_method :sprockets_headers, :headers
def headers(env, asset, length)
sprockets_headers(env, asset, length).tap do |headers|
# cache-bust .html assets because in our case they are frequently
AngularJS templates we need to tweak
if !path_fingerprint(env["PATH_INFO"]) &&
asset.pathname.basename.to_s[''.html'']
headers["Cache-Control"] = "max-age=0, private,
must-revalidate"
end
end
end
end
end
end
Would the ability to configure "Cache-Control" and other headers (or
add
headers) in responses for assets in Sprockets be helpful to have available
in Rails, or is it just assumed that if you need that level of control,
you''ll fix it elsewhere with nginx, apache, etc.?
Why I''m asking is that Heroku shows here how to change expiry of
actions:
https://devcenter.heroku.com/articles/http-caching-ruby-rails
but, I couldn''t find anywhere that talked about how to expire assets
other
than using digests/fingerprinting, until I came across server.rb in
sprockets and realized that it didn''t look like it was possible without
monkey patching or using another gem that would override the headers.
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-core/-/fgvsaflGLIcJ.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
Gary Weaver
2012-Dec-19 16:13 UTC
Re: cache-busting non-digest assets in sprockets in development a good idea? should headers in sprockets be configurable?
I also tried using digest in development and learned something: you can
change an asset by moving one section of the file to another section and
even though the file is thumbprinted/digested, sometimes the browser
won''t
reload it.
Basically, I changed config/environments/development.rb to use:
config.assets.debug = false
config.assets.digest = true
and much of the time if I move one section of the file to another part of
the same file (and I tried in a few different ways), the browser (FF 17 in
OS X) won''t reload the asset because it is still cached, even when I am
forcing Sprockets to cache-bust via this patch in
config/initializers/.../name_of_my_patch.rb
# Sprockets 2.x patch to cache-bust non-fingerprinted angular template html
in development
if Rails.env.development?
module Sprockets
module Server
private
# want to attempt to be compatible as much as possible so we''ll
call
their headers method ''sprockets_headers'' and then
# override just the headers we want. this may or may not work in
future versions as this is a private method.
alias_method :sprockets_headers, :headers
def headers(env, asset, length)
sprockets_headers(env, asset, length).tap do |headers|
# both digested/thumbprinted and non-digested files seem to not
refresh cache (at least with FF 17)
# so, use cache-busters for .../app/assets/**/*
if asset.pathname.to_s[''/app/assets/'']
puts "cache-busting #{asset.pathname.to_s}
etag_header=#{headers["ETag"]}
path_fingerprint(env[\"PATH_INFO\"])=#{path_fingerprint(env["PATH_INFO"])}"
headers["Cache-Control"] = "max-age=0, private,
must-revalidate"
end
end
end
end
end
end
However, with that patch, if I comment out the following:
#config.assets.debug = false
#config.assets.digest = true
It seems to work as intended.
On Tuesday, December 18, 2012 3:57:46 PM UTC-5, Gary Weaver
wrote:>
> Just monkey patched Sprockets in our Rails 3.2.9 app to override the
> Cache-Control header for html assets that we need to tweak more often in
> development, but that we don''t want to use digests/fingerprinting
with:
>
> # Sprockets 2.x patch
> if Rails.env.development?
> module Sprockets
> module Server
>
> private
> alias_method :sprockets_headers, :headers
>
> def headers(env, asset, length)
> sprockets_headers(env, asset, length).tap do |headers|
> # cache-bust .html assets because in our case they are
> frequently AngularJS templates we need to tweak
> if !path_fingerprint(env["PATH_INFO"]) &&
> asset.pathname.basename.to_s[''.html'']
> headers["Cache-Control"] = "max-age=0, private,
> must-revalidate"
> end
> end
> end
> end
> end
> end
>
> Would the ability to configure "Cache-Control" and other headers
(or add
> headers) in responses for assets in Sprockets be helpful to have available
> in Rails, or is it just assumed that if you need that level of control,
> you''ll fix it elsewhere with nginx, apache, etc.?
>
> Why I''m asking is that Heroku shows here how to change expiry of
actions:
> https://devcenter.heroku.com/articles/http-caching-ruby-rails
>
> but, I couldn''t find anywhere that talked about how to expire
assets other
> than using digests/fingerprinting, until I came across server.rb in
> sprockets and realized that it didn''t look like it was possible
without
> monkey patching or using another gem that would override the headers.
>
>
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-core/-/LjvlTx7rRFQJ.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-core+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.
Gary Weaver
2012-Dec-19 16:59 UTC
Re: cache-busting non-digest assets in sprockets in development a good idea? should headers in sprockets be configurable?
May not be a bug, really, but opened here for discussion, because it would seem that a file not changing its digest when it changes is a problem: https://github.com/sstephenson/sprockets/issues/399 On Wednesday, December 19, 2012 11:13:11 AM UTC-5, Gary Weaver wrote:> > I also tried using digest in development and learned something: you can > change an asset by moving one section of the file to another section and > even though the file is thumbprinted/digested, sometimes the browser won''t > reload it. > > Basically, I changed config/environments/development.rb to use: > > config.assets.debug = false > config.assets.digest = true > > and much of the time if I move one section of the file to another part of > the same file (and I tried in a few different ways), the browser (FF 17 in > OS X) won''t reload the asset because it is still cached, even when I am > forcing Sprockets to cache-bust via this patch in > config/initializers/.../name_of_my_patch.rb > > # Sprockets 2.x patch to cache-bust non-fingerprinted angular template > html in development > if Rails.env.development? > module Sprockets > module Server > > private > # want to attempt to be compatible as much as possible so we''ll call > their headers method ''sprockets_headers'' and then > # override just the headers we want. this may or may not work in > future versions as this is a private method. > alias_method :sprockets_headers, :headers > > def headers(env, asset, length) > sprockets_headers(env, asset, length).tap do |headers| > # both digested/thumbprinted and non-digested files seem to not > refresh cache (at least with FF 17) > # so, use cache-busters for .../app/assets/**/* > if asset.pathname.to_s[''/app/assets/''] > puts "cache-busting #{asset.pathname.to_s} > etag_header=#{headers["ETag"]} > path_fingerprint(env[\"PATH_INFO\"])=#{path_fingerprint(env["PATH_INFO"])}" > headers["Cache-Control"] = "max-age=0, private, > must-revalidate" > end > end > end > end > end > end > > However, with that patch, if I comment out the following: > > #config.assets.debug = false > #config.assets.digest = true > > It seems to work as intended. > > On Tuesday, December 18, 2012 3:57:46 PM UTC-5, Gary Weaver wrote: >> >> Just monkey patched Sprockets in our Rails 3.2.9 app to override the >> Cache-Control header for html assets that we need to tweak more often in >> development, but that we don''t want to use digests/fingerprinting with: >> >> # Sprockets 2.x patch >> if Rails.env.development? >> module Sprockets >> module Server >> >> private >> alias_method :sprockets_headers, :headers >> >> def headers(env, asset, length) >> sprockets_headers(env, asset, length).tap do |headers| >> # cache-bust .html assets because in our case they are >> frequently AngularJS templates we need to tweak >> if !path_fingerprint(env["PATH_INFO"]) && >> asset.pathname.basename.to_s[''.html''] >> headers["Cache-Control"] = "max-age=0, private, >> must-revalidate" >> end >> end >> end >> end >> end >> end >> >> Would the ability to configure "Cache-Control" and other headers (or add >> headers) in responses for assets in Sprockets be helpful to have available >> in Rails, or is it just assumed that if you need that level of control, >> you''ll fix it elsewhere with nginx, apache, etc.? >> >> Why I''m asking is that Heroku shows here how to change expiry of actions: >> https://devcenter.heroku.com/articles/http-caching-ruby-rails >> >> but, I couldn''t find anywhere that talked about how to expire assets >> other than using digests/fingerprinting, until I came across server.rb in >> sprockets and realized that it didn''t look like it was possible without >> monkey patching or using another gem that would override the headers. >> >>-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/HcNRNnZoz8gJ. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.