Module: Interlock::Finders
Public Instance Methods
caching_key (id)
Build the model cache key for a particular id.
# File lib/interlock/finders.rb, line 41 41: def caching_key(id) 42: Interlock.caching_key( 43: self.name, 44: "find", 45: id, 46: "default" 47: ) 48: end
find (*args)
Cached find.
Any other options besides ids short-circuit the cache, include an empty trailing Hash.
# File lib/interlock/finders.rb, line 10 10: def find(*args) 11: return find_via_db(*args) if args.last.is_a? Hash or args.first.is_a? Symbol 12: records = find_via_cache(args.flatten, true) 13: 14: if args.length > 1 or args.first.is_a? Array 15: records 16: else 17: records.first 18: end 19: 20: end
find_all_by_id (*args)
Cached find_all_by_id. Ultrasphinx uses this. Short-circuiting works the same as find.
# File lib/interlock/finders.rb, line 33 33: def find_all_by_id(*args) 34: return method_missing(:find_all_by_id, *args) if args.last.is_a? Hash 35: find_via_cache(args, false) 36: end
find_by_id (*args)
Cached find_by_id. Short-circuiting works the same as find.
# File lib/interlock/finders.rb, line 25 25: def find_by_id(*args) 26: return method_missing(:find_by_id, *args) if args.last.is_a? Hash 27: find_via_cache(args, false).first 28: end
Private Instance Methods
find_via_cache (ids, should_raise)
# File lib/interlock/finders.rb, line 52 52: def find_via_cache(ids, should_raise) #:doc: 53: results = [] 54: 55: ordered_keys_to_ids = ids.map { |id| [caching_key(id), id.to_i] } 56: keys_to_ids = Hash[*ordered_keys_to_ids.flatten] 57: 58: records = {} 59: 60: if ActionController::Base.perform_caching 61: load_from_local_cache(records, keys_to_ids) 62: load_from_memcached(records, keys_to_ids) 63: end 64: 65: load_from_db(records, keys_to_ids) 66: 67: # Put them in order 68: 69: ordered_keys_to_ids.each do |key, | 70: record = records[key] 71: raise ActiveRecord::RecordNotFound, "Couldn't find #{self.name} with ID=#{keys_to_ids[key]}" if should_raise and !record 72: results << record 73: end 74: 75: results 76: end
load_from_db (current, keys_to_ids)
# File lib/interlock/finders.rb, line 106 106: def load_from_db(current, keys_to_ids) #:doc: 107: # Drop to db if necessary 108: if current.size < keys_to_ids.size 109: missed = keys_to_ids.reject { |key, | current[key] } 110: ids_to_keys = keys_to_ids.invert 111: 112: # Load from the db 113: records = find_all_by_id(missed.values, {}) 114: records = Hash[*(records.map do |record| 115: [ids_to_keys[record.id], record] 116: end.flatten)] 117: 118: # Set missed to the caches 119: records.each do |key, value| 120: Interlock.say key, "is loading from the db", "model" 121: Interlock.local_cache.write(key, value, nil) 122: CACHE.set key, value 123: end 124: 125: current.merge!(records) 126: end 127: end
load_from_local_cache (current, keys_to_ids)
# File lib/interlock/finders.rb, line 78 78: def load_from_local_cache(current, keys_to_ids) #:doc: 79: # Load from the local cache 80: records = {} 81: keys_to_ids.each do |key, | 82: record = Interlock.local_cache.read(key, nil) 83: records[key] = record if record 84: end 85: current.merge!(records) 86: end
load_from_memcached (current, keys_to_ids)
# File lib/interlock/finders.rb, line 88 88: def load_from_memcached(current, keys_to_ids) #:doc: 89: # Drop to memcached if necessary 90: if current.size < keys_to_ids.size 91: records = {} 92: missed = keys_to_ids.reject { |key, | current[key] } 93: 94: records = CACHE.get_multi(*missed.keys) 95: 96: # Set missed to the caches 97: records.each do |key, value| 98: Interlock.say key, "is loading from memcached", "model" 99: Interlock.local_cache.write(key, value, nil) 100: end 101: 102: current.merge!(records) 103: end 104: end