File: lib/radiant/cache.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Rack
  module: Cache
  class: MetaStore#98
inherits from
  Object ( Builtin-Module )
has properties
constant: RADIANT #99
  class: EntityStore#94
inherits from
  Object ( Builtin-Module )
has properties
constant: RADIANT #95
  module: Radiant#7
  module: Cache#8
has properties
module method: new / 2 #15
module method: clear #27
  class: EntityStore#32
inherits from
  Disk ( Rack::Cache::EntityStore )
has properties
method: initialize / 1 #33
method: clear #38
method: write / 1 #42
  class: MetaStore#49
inherits from
  Disk ( Rack::Cache::MetaStore )
has properties
method: initialize / 1 #50
method: clear #55
method: store / 3 #59
method: restore_response / 2 #66
method: accelerate / 3 #83

Code

   1  require 'rack/cache'
   2  # So we can subclass the storage types
   3  require 'rack/cache/storage'
   4  require 'rack/cache/metastore'
   5  require 'rack/cache/entitystore'
   6 
   7  module Radiant
   8    module Cache
   9      mattr_accessor :meta_stores, :entity_stores, :use_x_sendfile, :use_x_accel_redirect
  10      self.meta_stores ||= []
  11      self.entity_stores ||= []
  12      self.use_x_sendfile = false
  13      self.use_x_accel_redirect = nil
  14 
  15      def self.new(app, options={})
  16        self.use_x_sendfile = options.delete(:use_x_sendfile) if options[:use_x_sendfile]
  17        self.use_x_accel_redirect = options.delete(:use_x_accel_redirect) if options[:use_x_accel_redirect]
  18        Rack::Cache.new(app, {
  19            :private_headers => ['Authorization'],
  20            :entitystore => "radiant:tmp/cache/entity",
  21            :metastore => "radiant:tmp/cache/meta",
  22            :verbose => false,
  23            :allow_reload => false,
  24            :allow_revalidate => false}.merge(options))
  25      end
  26 
  27      def self.clear
  28        meta_stores.each {|ms| ms.clear }
  29        entity_stores.each {|es| es.clear }
  30      end
  31 
  32      class EntityStore < Rack::Cache::EntityStore::Disk
  33        def initialize(root="#{Rails.root}/tmp/cache/entity")
  34          super
  35          Radiant::Cache.entity_stores << self
  36        end
  37 
  38        def clear
  39          Dir[File.join(self.root, "*")].each {|file| FileUtils.rm_rf(file) }
  40        end
  41        
  42        def write(body)
  43          # Verify that the cache directory exists before attempting to write
  44          FileUtils.mkdir_p(self.root, :mode => 0755) unless File.directory?(self.root)
  45          super
  46        end
  47      end
  48 
  49      class MetaStore < Rack::Cache::MetaStore::Disk
  50        def initialize(root="#{Rails.root}/tmp/cache/meta")
  51          super
  52          Radiant::Cache.meta_stores << self
  53        end
  54 
  55        def clear
  56          Dir[File.join(self.root, "*")].each {|file| FileUtils.rm_rf(file) }
  57        end
  58 
  59        def store(request, response, entitystore)
  60          # Verify that the cache directory exists before attempting to store
  61          FileUtils.mkdir_p(self.root, :mode => 0755) unless File.directory?(self.root)
  62          super
  63        end
  64 
  65        private
  66        def restore_response(hash, body=nil)
  67          # Cribbed from the Rack::Cache source
  68          status = hash.delete('X-Status').to_i
  69          response = Rack::Cache::Response.new(status, hash, body)
  70 
  71          # Add acceleration headers
  72          if Radiant::Cache.use_x_sendfile
  73            accelerate(response, 'X-Sendfile', File.expand_path(body.path))
  74          elsif Radiant::Cache.use_x_accel_redirect
  75            virtual_path = File.expand_path(body.path)
  76            entity_path = File.expand_path(Radiant::Cache.entity_stores.first.root)
  77            virtual_path[entity_path] = Radiant::Cache.use_x_accel_redirect
  78            accelerate(response,'X-Accel-Redirect', virtual_path)
  79          end
  80          response
  81        end
  82 
  83        def accelerate(response, header, value)
  84          response.headers[header] = value
  85          response.body = []
  86          response.headers['Content-Length'] = '0'
  87        end
  88      end
  89    end
  90  end
  91 
  92  # Rack::Cache will look for a constant matching the uri scheme given to the :metastore and :entitystore options
  93  # when initialising the Middleware
  94  class Rack::Cache::EntityStore
  95    RADIANT = Radiant::Cache::EntityStore
  96  end
  97 
  98  class Rack::Cache::MetaStore
  99    RADIANT = Radiant::Cache::MetaStore
 100  en