3

I've been having some caching problems with a footer that is shared across multiple sites, and I'm wondering what might be up. Here's the error message and the backtrace:

 Cache read: remote_footer_information ({:expires_in=>300 seconds})
 Cache generate: remote_footer_information ({:expires_in=>300 seconds})
 Cache write: remote_footer_information ({:expires_in=>300 seconds})
 Marshalling error for key 'remote_footer_information': no _dump_data is defined for class Proc
 You are trying to cache a Ruby object which cannot be serialized to memcached.

 /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/server.rb:397:in `dump'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/server.rb:397:in `serialize'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/server.rb:269:in `set'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/server.rb:60:in `request'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/options.rb:18:in `block in request'
    /app/vendor/ruby-1.9.3/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/options.rb:17:in `request'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/client.rb:348:in `perform'
    /app/vendor/bundle/ruby/1.9.1/gems/dalli-2.6.4/lib/dalli/client.rb:199:in `set'
    (eval):7:in `block in set_with_newrelic_trace'
    ...

Here's the place where the cache retrieval is being defined:

require 'httparty'

module Myclassname
  class Footer
    include HTTParty
    format :json
    attr_accessor :response

    def initialize
      @response = Rails.cache.fetch("remote_footer_information", :expires_in => 5.minutes) do
        begin
          self.class.get("http://www.myappname.net/pages/my_footer.json")
        rescue
          false
        end
      end
    end

    def valid?
      unless @response == false || @response.blank?
        return @response['footer'] != nil
      end

      false
    end

    def footer
      unless @response == false || @response.blank?
        return @response['footer']
      end

      nil
    end

  end
end

And here's the place in the view where this is being called.

<%= yield :footer_legend %>

<div class="clearer"></div>
<div class="divider">
</div>

<% response = Myclassname::Footer.new %>
<% if response && response.valid? %>
    <%= response.footer.html_safe %>
<% end %>

What am I doing wrong here? Any ideas would be greatly appreciated. Thanks!

4

3 回答 3

8

显然Httparty::Response返回的对象Httparty.get是不可序列化的,需要缓存。尝试只缓存您需要的部分响应,例如

response = self.class.get("http://www.myappname.net/pages/my_footer.json")
response['footer'] if response

此处描述了该问题。

于 2013-10-28T03:05:00.000 回答
1

将 HTTParty 响应转换为哈希对我有用。

Rails.cache.fetch(cache_key) do
  HTTParty.get(url).to_hash
end
于 2016-06-03T22:51:25.107 回答
0

从 httparty 版本0.16.3 开始。HTTParty::Response 对象是可缓存的。

例如,您现在可以开箱即用地将响应对象缓存在缓存存储中:

response = HTTParty.get(...)

store.set(key, Marshal.dump(response))
于 2019-01-03T16:41:13.200 回答