Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | leonardo-soto |
View: | 1,788 times |
Download: | 0 times |
Leo Soto M.ContinuumLecture & Beef, Marzo 2013
Caching tips
Sunday, March 3, 13
Leo Soto M.ContinuumLecture & Beef, Marzoss 2013
Caching tips (for webapps)
Sunday, March 3, 13
“There are only two hard things in computer science...
Sunday, March 3, 13
...cache invalidation and naming things”
- Phil Karlton
Sunday, March 3, 13
HTTP Caching
•Client-side!
•...or “middle-side” (proxys!)
•Conceptos claves:
•Frescura (freshness)
•Validacion/Invalidacion
Sunday, March 3, 13
FRESH CACHES
•HTTP/1.0:
Expires: Fri, 01 March 2013 20:00:00 GMT
•HTTP/1.1:
Cache-‐Control: *pila-‐de-‐opciones*
Cache-‐Control: private, max-‐age=3600
Sunday, March 3, 13
VALIDATED CACHES
•HTTP/1.0:
Last-‐Modified / If-‐Modified-‐Since
304 Not Modified
•HTTP/1.1:
ETag / If-‐None-‐Match
304 Not Modified
Sunday, March 3, 13
CACHE INVALIDATION
•METODOS HTTP QUE INVALIDAN CACHES FRESCAS:
POST /resource
DELETE /resource
PUT /resource
Sunday, March 3, 13
EN RAILS
•FRESH CACHES:
expires_in 1.hour
•VALIDATED CACHES
if stale?(etag: @modelo)
otros_hits_a_la_bd
end
Sunday, March 3, 13
stale?(etag: x) -‐> Etag: md5(expand_cache_key(x))# File activesupport/lib/active_support/cache.rb, line 77def expand_cache_key(key, namespace = nil) expanded_cache_key = namespace ? "#{namespace}/" : ""
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] expanded_cache_key << "#{prefix}/" end
expanded_cache_key << retrieve_cache_key(key) expanded_cache_keyend
# File activesupport/lib/active_support/cache.rb, line 90def retrieve_cache_key(key) case when key.respond_to?(:cache_key) then key.cache_key when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param else end.to_send
Sunday, March 3, 13
# File activerecord/lib/active_record/integration.rb, line 37def cache_key case when new_record? "#{self.class.model_name.cache_key}/new" when timestamp = self[:updated_at] timestamp = timestamp.utc.to_s(:number) "#{self.class.model_name.cache_key}/#{id}-#{timestamp}" else "#{self.class.model_name.cache_key}/#{id}" endend
Sunday, March 3, 13
EN RAILS
•SIN ETAGGER
stale?(etag: [current_user, @modelo])
stale?(etag: [current_user, @otro])
stale?(etag: [current_user, @otromas])
Sunday, March 3, 13
EN RAILS
•CON ETAGGERetag { current_user }
stale?(etag: modelo)
stale?(etag: otro)
stale?(etag: otromas)
Sunday, March 3, 13
EN RAILS
•EN AC PERFORACIONESetag { [current_user, ENV[‘COMMIT_HASH’] }
stale?(etag: modelo)
stale?(etag: otro)
stale?(etag: otromas)
Sunday, March 3, 13
Rails Fragment Caching
-‐cache ‘foo’ do...end
-‐cache modelo do...end
-‐cache [reporte, ‘inbox’] do..end
# File actionpack/lib/action_controller/caching/fragments.rb, line 51def fragment_cache_key(key) ActiveSupport::Cache.expand_cache_key( key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)end
Sunday, March 3, 13
RUSSIAN DOLL CACHING
-‐ cache [reporte, ‘perforaciones’] do
-‐ perforacion.each do |p|
-‐ cache perforacion do
%h1= perforacion.titulo
%p= perforacion.whatever
Sunday, March 3, 13
TIPS FRAGMENT CACHING
•Aplicar a cosas que no dependan del usuario actual
•Usar cache_digests + memcached
Sunday, March 3, 13
CONCLUSIONES
•HTTP CACHING:
•CACHE LOCAL AL USUARIO
•AHORRA:
•LATENCIA
•ANCHO DE BANDA,
•TIEMPO DE RESPUESTA DEL SERVIDOR
Sunday, March 3, 13
CONCLUSIONES
•FRAGMENT CACHING:
•CACHE GLOBAL DE LA APP
•AHORRA:
•HITS A LA BD
•CALCULOS
•RENDERING
Sunday, March 3, 13
BONUS TRACK def prefetch(url) content_tag("script", %Q{ $("<link href='#{escape_javascript(url)}' rel='subresource'/>").appendTo('head') }.html_safe ) unless current_page?(url) end
def tab_detalle_reporte(text, opts = {}) collection = opts[:collection] || text.downcase.pluralize url = send("reporte_#{collection}_path", estado, reporte) tab_title(opts.merge!( name: text, href: url, active: tab == collection )) + prefetch(url) end
Sunday, March 3, 13