aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/cache.rb
blob: 8252ada032f5ac5765713789ca92a5275e1a89c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
module ActiveSupport
  module Cache
    def self.lookup_store(*store_option)
      store, *parameters = *([ store_option ].flatten)

      case store
      when Symbol
        store_class_name = (store == :drb_store ? "DRbStore" : store.to_s.camelize)
        store_class = ActiveSupport::Cache.const_get(store_class_name)
        store_class.new(*parameters)
      when nil
        ActiveSupport::Cache::MemoryStore.new
      else
        store
      end
    end

    def self.expand_cache_key(key, namespace = nil)
      expanded_cache_key = namespace ? "#{namespace}/" : ""
      
      if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
        expanded_cache_key << "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/" 
      end

      expanded_cache_key << case
      when key.respond_to?(:cache_key)
        key.cache_key
      when key.is_a?(Array)
        key.collect { |element| expand_cache_key(element) }.to_param
      when key.respond_to?(:to_param)
        key.to_param
      end

      expanded_cache_key
    end


    class Store
      cattr_accessor :logger

      def initialize
      end

      def threadsafe!
        @mutex = Mutex.new
        self.class.send :include, ThreadSafety
        self
      end

      def fetch(key, options = nil)
        @logger_off = true        
        if value = read(key, options)
          @logger_off = false
          log("hit", key, options)
          value
        elsif block_given?
          @logger_off = false
          log("miss", key, options)

          value = nil
          seconds = Benchmark.realtime { value = yield }

          @logger_off = true
          write(key, value, options)
          @logger_off = false

          log("write (will save #{'%.5f' % seconds})", key, nil)

          value
        end
      end

      def read(key, options = nil)
        log("read", key, options)
      end

      def write(key, value, options = nil)
        log("write", key, options)
      end

      def delete(key, options = nil)
        log("delete", key, options)
      end

      def delete_matched(matcher, options = nil)
        log("delete matched", matcher.inspect, options)
      end

      
      private
        def log(operation, key, options)
          logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@logger_off
        end
    end


    module ThreadSafety #:nodoc:
      def read(key, options = nil) #:nodoc:
        @mutex.synchronize { super }
      end

      def write(key, value, options = nil) #:nodoc:
        @mutex.synchronize { super }
      end

      def delete(key, options = nil) #:nodoc:
        @mutex.synchronize { super }
      end

      def delete_matched(matcher, options = nil) #:nodoc:
        @mutex.synchronize { super }
      end
    end
  end
end

require 'active_support/cache/file_store'
require 'active_support/cache/memory_store'
require 'active_support/cache/drb_store'
require 'active_support/cache/mem_cache_store'
require 'active_support/cache/compressed_mem_cache_store'