| Class | ApplicationCache |
| In: |
app/models/application_cache.rb
|
| Parent: | Object |
API for interaction with the cache, and it‘s related data model.
Determine if cached data exists for the given id, and if so, then retrieve and return it.
# 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.
# 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.
# 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.
# 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.
# 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().
# 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.
# 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.
# 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