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