File: active_support/cache/strategy/local_cache.rb

Overview
Module Structure
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: ActiveSupport#1
  module: Cache#2
  module: Strategy#3
  module: LocalCache#4
has properties
constant: NULL #6
method: with_local_cache #8
method: middleware #15
method: read / 2 #34
method: write / 3 #48
method: delete / 2 #54
method: exist / 2 #59
method: increment / 2 #70
method: decrement / 2 #79
method: clear #88
method: thread_local_key #94
method: local_cache #98

Code

   1  module ActiveSupport
   2    module Cache
   3      module Strategy
   4        module LocalCache
   5          # this allows caching of the fact that there is nothing in the remote cache
   6          NULL = 'remote_cache_store:null'
   7 
   8          def with_local_cache
   9            Thread.current[thread_local_key] = MemoryStore.new
  10            yield
  11          ensure
  12            Thread.current[thread_local_key] = nil
  13          end
  14 
  15          def middleware
  16            @middleware ||= begin
  17              klass = Class.new
  18              klass.class_eval(<<-EOS, __FILE__, __LINE__ + 1)
  19                def initialize(app)
  20                  @app = app
  21                end
  22 
  23                def call(env)
  24                  Thread.current[:#{thread_local_key}] = MemoryStore.new
  25                  @app.call(env)
  26                ensure
  27                  Thread.current[:#{thread_local_key}] = nil
  28                end
  29              EOS
  30              klass
  31            end
  32          end
  33 
  34          def read(key, options = nil)
  35            value = local_cache && local_cache.read(key)
  36            if value == NULL
  37              nil
  38            elsif value.nil?
  39              value = super
  40              local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
  41              value.duplicable? ? value.dup : value
  42            else
  43              # forcing the value to be immutable
  44              value.duplicable? ? value.dup : value
  45            end
  46          end
  47 
  48          def write(key, value, options = nil)
  49            value = value.to_s if respond_to?(:raw?) && raw?(options)
  50            local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
  51            super
  52          end
  53 
  54          def delete(key, options = nil)
  55            local_cache.mute { local_cache.write(key, NULL) } if local_cache
  56            super
  57          end
  58 
  59          def exist(key, options = nil)
  60            value = local_cache.read(key) if local_cache
  61            if value == NULL
  62              false
  63            elsif value
  64              true
  65            else
  66              super
  67            end
  68          end
  69 
  70          def increment(key, amount = 1)
  71            if value = super
  72              local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
  73              value
  74            else
  75              nil
  76            end
  77          end
  78 
  79          def decrement(key, amount = 1)
  80            if value = super
  81              local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
  82              value
  83            else
  84              nil
  85            end
  86          end
  87 
  88          def clear
  89            local_cache.clear if local_cache
  90            super
  91          end
  92 
  93          private
  94            def thread_local_key
  95              @thread_local_key ||= "#{self.class.name.underscore}_local_cache".gsub("/", "_").to_sym
  96            end
  97 
  98            def local_cache
  99              Thread.current[thread_local_key]
 100            end
 101        end
 102      end
 103    end
 104  end