views:

45

answers:

1

Hi Stackoverflowers, I have spent way too much time on this issue to keep my sanity so it is time to ask for help...

I have a class with this method:

def telecom_info

    Rails.cache.fetch("telecom_info_for_#{ref_num}", :expires_in=> 3.hours) do
      info = Hash.new(0)
      Telecom::SERVICES.each do |source|
          results = TelecomUsage.find(:all, 
                                      :joins=>[:telecom_invoice=>{ :person=> :org_person}], 
                                      :conditions=>"dotted_ids like '%#{ref_num}%' and telecom_usages.ruby_type = '#{source}'", 
                                      :select=>"avg(charge) #{source.upcase}_AVG_CHARGE,
                                                max(charge) #{source.upcase}_MAX_CHARGE,
                                                min(charge) #{source.upcase}_MIN_CHARGE,
                                                sum(charge) #{source.upcase}_CHARGE,

                                                avg(volume) #{source.upcase}_AVG_VOLUME,
                                                max(volume) #{source.upcase}_MAX_VOLUME,
                                                min(volume) #{source.upcase}_MIN_VOLUME,
                                                sum(volume) #{source.upcase}_VOLUME
                                                ")

          results = results.first
          ['charge', 'volume'].each do |source_type|                                        
            info["#{source}_#{source_type}".to_sym] = results.send("#{source}_#{source_type}".downcase).to_i
            info["#{source}_min_#{source_type}".to_sym] = results.send("#{source}_min_#{source_type}".downcase).to_i
            info["#{source}_max_#{source_type}".to_sym] = results.send("#{source}_max_#{source_type}".downcase).to_i
            info["#{source}_avg_#{source_type}".to_sym] = results.send("#{source}_avg_#{source_type}".downcase).to_i
          end
      end

      return info
    end
end

As you can see, this is an expensive call, and it is called ALOT for each request so I want to cache it. The problem is that memcached does not seem to work, in the log file, I am getting:

Cache read: telecom_info_for_60000000

Cache miss: telecom_info_for_60000000 ({})

The weird thing is that I know memcached is working since it does cache the results of some other functions I have in another model.

Any suggestions? I am running Rails 2.3.5 on REE 1.8.7

+4  A: 

Replace return info with info.

Rails.cache.fetch("telecom_info_for_#{ref_num}", :expires_in=> 3.hours) do
  # ...
  info
end

The return keyword always returns from the current method, which means that info is never returned to your call to Rails.cache.fetch, nor is the rest of that method ever executed. When the last statement simply is info, this is the value that will be given to Rails.cache.fetch, and you will allow the method to finish its duty by storing this value in the cache.

Compare the following:

def my_method
  1.upto(3) do |i|
    # Calling return immediately causes Ruby to exit the current method.
    return i
  end
end

my_method
#=> 1

As a rule of thumb: always omit return unless you really mean to exit the current block and return from the current method.

molf
Confusing.. O_o (At least for a Ruby/RoR beginner)
randomguy
Thanks, no more return for me then! ;-)
Alain