【问题标题】:How to cache Weather (Nokogiri::XML::NodeSet object) in Memcache?如何在 Memcache 中缓存天气(Nokogiri::XML::NodeSet 对象)?
【发布时间】:2015-08-10 10:07:57
【问题描述】:

我正在尝试在 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'

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

【问题讨论】:

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


    【解决方案1】:

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

    原因是yahoo_weatherman gem 的ResponseNokogiri::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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-07
      • 2021-01-20
      • 2017-09-15
      • 2017-10-30
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多