如何在Memcache中缓存Weather(Nokogiri :: XML :: NodeSet对象)?

时间:2015-08-10 10:07:58

标签: ruby-on-rails ruby memcached nokogiri dalli

我正在尝试在Memcache中缓存Weatherman的响应(https://github.com/dlt/yahoo_weatherman)以避免多次获取天气,我正在做:

  weather = Rails.cache.fetch([:weather_by_woeid, weather.woeid], expires_in: 1.hour) do
    client = Weatherman::Client.new
    client.lookup_by_woeid weather.woeid
  end

但是我得到了这个例外:

ERROR -- : Marshalling error for key 'Timeline:weather_by_woeid/26352062': no _dump_data is defined for class Nokogiri::XML::NodeSet
ERROR -- : You are trying to cache a Ruby object which cannot be serialized to memcached.
ERROR -- : /var/lib/gems/2.2.0/gems/dalli-2.7.4/lib/dalli/server.rb:402:in `dump'

处理此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

对于yahoo_weatherman gem的给定代码库,这是不可能的。

原因是Response gem的yahoo_weathermanNokogiri::XML::NodeSet的形式封装了XML响应,无法序列化,因此无法缓存。

为了解决这个问题,我们可以对Weathernan::Client类进行修补,以便我们可以访问Weatherman API的原始响应,这是一个字符串并且可以被缓存。

# Extends the default implementation by a method that can give us raw response
class Weatherman::Client
    def lookup_raw_by_woeid(woeid)
        raw = get request_url(woeid)
    end
end

# We call the lookup_raw_by_woeid and cache its response (string)
weather = Rails.cache.fetch([:weather_by_woeid, weather.woeid], expires_in: 1.hour) do
    client = Weatherman::Client.new
    client.lookup_raw_by_woeid weather.woeid
end

# We now convert that string into a Weatherman response.
w = Weatherman::Response.new(weather)

# Print some values from weather response
p w.wind