Module: Plum::StaticCache
- Defined in:
- lib/plum/static_cache.rb,
lib/plum/static_cache/middleware.rb
Overview
Full-page static cache. Rendered public pages are written to disk keyed by host + path; subsequent requests are served from the file without touching the database or Liquid. A web server can serve the same files directly (nginx try_files) for the "full measure" where Rails never sees the hit.
Cache entries are invalidated by deletion (see StaticCacheInvalidation) — the next request re-renders and re-stores the page. Over-flushing is cheap, so anything ambiguous flushes the whole site.
Defined Under Namespace
Classes: Middleware
Constant Summary collapse
- MARKER_HEADER =
"X-Plum-Static-Cache".freeze
Class Method Summary collapse
- .cache_root ⇒ Object
- .content_type_for(file) ⇒ Object
-
.enabled? ⇒ Boolean
Explicit opt-in only — see docs/static-caching.md.
-
.file_path(host, path) ⇒ Object
Pages are stored as host/path/index.html so a web server can map URLs to files directly.
- .flush_all! ⇒ Object
- .flush_site!(site) ⇒ Object
- .read(host, path) ⇒ Object
- .store(host, path, body) ⇒ Object
Class Method Details
.cache_root ⇒ Object
24 25 26 |
# File 'lib/plum/static_cache.rb', line 24 def cache_root Pathname(Plum.configuration.static_cache_path || Rails.root.join("storage", "plum_static_cache")) end |
.content_type_for(file) ⇒ Object
77 78 79 |
# File 'lib/plum/static_cache.rb', line 77 def content_type_for(file) Rack::Mime.mime_type(File.extname(file.to_s), "text/html") end |
.enabled? ⇒ Boolean
Explicit opt-in only — see docs/static-caching.md. There is deliberately no "auto-on in production" mode: this cache is only correct on a single-server deployment, and defaulting it on would silently corrupt pages the moment an app scales to 2+ nodes.
20 21 22 |
# File 'lib/plum/static_cache.rb', line 20 def enabled? !!Plum.configuration.static_cache_enabled end |
.file_path(host, path) ⇒ Object
Pages are stored as host/path/index.html so a web server can map URLs to files directly. Paths with a file extension (theme assets) are stored verbatim.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/plum/static_cache.rb', line 31 def file_path(host, path) key = normalized_path(path) return nil unless key base = cache_root.join(sanitized_host(host)) full = File.extname(key).present? ? base.join(key) : base.join(key, "index.html") full = Pathname(File.(full)) return nil unless full.to_s.start_with?(cache_root.to_s + File::SEPARATOR) full end |
.flush_all! ⇒ Object
71 72 73 74 75 |
# File 'lib/plum/static_cache.rb', line 71 def flush_all! return unless cache_root.exist? cache_root.children.each { |child| FileUtils.rm_rf(child) } end |
.flush_site!(site) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/plum/static_cache.rb', line 62 def flush_site!(site) return flush_all! if site.nil? || site.domain.blank? [ site.domain, "www.#{site.domain}" ].each do |host| dir = cache_root.join(sanitized_host(host)) FileUtils.rm_rf(dir) if dir.to_s.start_with?(cache_root.to_s) && dir.exist? end end |
.read(host, path) ⇒ Object
43 44 45 46 |
# File 'lib/plum/static_cache.rb', line 43 def read(host, path) file = file_path(host, path) file if file&.file? end |
.store(host, path, body) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/plum/static_cache.rb', line 48 def store(host, path, body) file = file_path(host, path) return unless file file.dirname.mkpath tmp = file.sub_ext(".tmp-#{Process.pid}-#{Thread.current.object_id}") tmp.binwrite(body) File.rename(tmp, file) file rescue SystemCallError => e Rails.logger.error("[Plum] static cache write failed for #{path}: #{e.}") nil end |