Class ApplicationCache
In: app/models/application_cache.rb
Parent: Object

API for interaction with the cache, and it‘s related data model.

Methods

Public Class methods

Determine if cached data exists for the given id, and if so, then retrieve and return it.

[Source]

    # File app/models/application_cache.rb, line 16
16:   def self.get (
17:     id
18:   )
19:     if (o('application:cache:enabled'))
20:       cache_id = get_cache_id(id)
21:   
22:       # An in-memory list of cached ids is maintained rather than looking for
23:       # this file in the disk cache every time, for performance reasons.
24:       if ($cache['index'][cache_id])
25:         record_hit(id) if (o('application:cache:record_hits'))
26:   
27:         # If an id exists in $cache['index'] then its data file is presumed 
28:         # to exist.
29:         begin
30:           data = ''
31:           File.open(CACHE_FILE.parse_data(cache_id)) { |f| data = f.read }
32:           return data
33:         rescue
34:           l(m(8, cache_id, id))
35:         end
36:       end
37:   
38:       # The requested data was unavailable.
39:       record_miss(id) if (o('application:cache:record_misses'))
40:     end
41: 
42: 
43:     # If we have not returned yet, caching is disabled or data is unavailable.
44:     return FALSE
45:   end

Construct a cache identifier based on a string value.

[Source]

    # File app/models/application_cache.rb, line 51
51:   def self.get_cache_id (
52:     id
53:   )
54:     Digest::MD5.hexdigest(id)
55:   end

Configure and populate the cache data index.

[Source]

    # File app/models/application_cache.rb, line 61
61:   def self.initialize_index
62:     if (!$cache['index'])
63:       # Configure the index as a hash.
64:       $cache['index'] = {}
65: 
66:       # If an index file exists then use it to populate the cache index.
67:       if (File.readable?(CACHE_INDEX))
68:         index_file = File.open(CACHE_INDEX)
69: 
70:         begin
71:           # Obtain the cache id from the current line.
72:           while cache_id = index_file.readline.chomp.split('|')[1]
73:             # Only initialize hash entries that do not exist, and for which 
74:             # a cache data file does exist.
75:             if (File.readable?(CACHE_FILE.parse_data(cache_id)) && 
76:                 !$cache['index'][cache_id])
77:               $cache['index'][cache_id] = TRUE
78:             end
79:           end
80:         rescue EOFError
81:           index_file.close
82:         end
83:       end
84:     end
85:   end

Maintain a counter for found data.

[Source]

    # File app/models/application_cache.rb, line 91
91:   def self.record_hit (
92:     id
93:   )
94:     record_stat('hit', id)
95:   end

Maintain a counter for unfound data.

[Source]

     # File app/models/application_cache.rb, line 101
101:   def self.record_miss (
102:     id
103:   )
104:     record_stat('miss', id)
105:   end

Maintain a hit counter for cache requests.

s() provides a global counter, on a per name basis.

The argument to this method, id, must be in the format returned by get_cache_id().

[Source]

     # File app/models/application_cache.rb, line 116
116:   def self.record_stat (
117:     type,
118:     id
119:   )
120:     ($cache[type][id]) ? (count = $cache[type][id] + 1) : (count = 1)
121:     $cache[type][id] = count
122:     count
123:   end

Store cache data.

[Source]

     # File app/models/application_cache.rb, line 129
129:   def self.set (
130:     id,
131:     data
132:   )
133:     if (o('application:cache:enabled'))
134:       cache_id = get_cache_id(id)
135:   
136:       # CACHE_FILE is presumed to be writable.
137:       begin
138:         # Write this data to a cache file, overwriting any existing files.
139:         #
140:         # NOTE:
141:         # Failure to update the cache index file - the result of the call to 
142:         # update_index() below - is ignored, and the cache data file is still 
143:         # created, as it is still accessible via $cache['index'].
144:         cache = File.new(CACHE_FILE.parse_data(cache_id), 'w')
145:         cache.puts data
146:         cache.close
147:   
148:         # If data has already been cached but the cache data file has become 
149:         # corrupt then the application will re-create the file (this is done 
150:         # immediately above). In this case there is no need to update
151:         # $cache['index'] or the CACHE_INDEX file, so ignore these updates by
152:         # examining $cache['index'][cache_id] to see if it is already TRUE.
153:         #
154:         # NOTE:
155:         # This conditional must follow cache data file creation: if it is not
156:         # possible to write to the cache data file then an exception will be
157:         # thrown and this conditional will not be executed, thus the integrity
158:         # of $cache['index'] and the CACHE_INDEX file will be maintained.
159:         if (!$cache['index'][cache_id])
160:           # Record the id of this data in the list of all ids that are cached. 
161:           $cache['index'][cache_id] = TRUE
162:   
163:           # Update the cache index map file.
164:           update_index(id, cache_id)
165:         end
166:   
167:         return TRUE
168:       rescue
169:         l(m(9, cache_id, id))
170:       end
171:     end
172: 
173: 
174:     return FALSE
175:   end

Maintain a map file, relating URIs to their cache file names.

[Source]

     # File app/models/application_cache.rb, line 181
181:   def self.update_index (
182:     id,
183:     cache_id
184:   )
185:     # CACHE_INDEX is presumed to be writable.
186:     begin
187:       file = File.new(CACHE_INDEX, 'a')
188:       file.puts CACHE_INDEX_DATA.parse_data(id, cache_id)
189:       file.close
190: 
191:       return TRUE
192:     rescue
193:       l(m(10, CACHE_INDEX, cache_id, id))
194:       return FALSE
195:     end
196:   end

[Validate]