带有expires_in的Rails.cache.fetch只有在新值不为nil时才会过期

时间:2013-07-27 11:37:54

标签: ruby-on-rails caching fetch null

我想做一个简单的Rails.cache.fetch并在大约10分钟后过期。缓存中充满了来自外部API的json数据。但是,有时无法访问外部API。因此,当缓存过期并尝试获取新的json数据时,缓存内容将无效。

如果fetch_json返回有效数据,我怎样才能使Rails.cache.fetch只覆盖缓存?但是,如果收到新的有效数据,缓存应在10分钟后过期。

这是我尝试这样做的方式,但它不起作用。更好的代码突出显示在这个要点:https://gist.github.com/i42n/6094528

有关我如何才能完成这项工作的任何提示?

module ExternalApiHelper

    require 'timeout'
    require 'net/http'

    def self.fetch_json(url)
        begin
            result = Timeout::timeout(2) do # 2 seconds
                # operation that may cause a timeout
                uri = URI.parse(url)
                http = Net::HTTP.new(uri.host, uri.port)
                request = Net::HTTP::Get.new(uri.request_uri)
                response = http.request(request)
                return JSON.parse(response.body)
            end
            return result
        rescue
            # if any error happens in the block above, return empty string
            # this will result in fetch_json_with_cache using the last value in cache
            # as long as no new data arrives
            return ""
        end
    end

    def self.fetch_json_with_cache(url, expire_time)
        cache_backup = Rails.cache.read(url)
        api_data = Rails.cache.fetch(url, :expires_in => expire_time) do
            new_data = fetch_json(url)
            if new_data.blank?
                # if API fetch did not return valid data, return the old cache state
                cache_backup
            else
                new_data
            end
        end
        return api_data
    end

end

1 个答案:

答案 0 :(得分:1)