I want to do a simple Rails.cache.fetch
and expire it after about 10 minutes. The cache gets filled with json data from an external API. However the external API is not reachable sometimes. So when the cache expires and tries to fetch new json data, the cache content gets invalid.
How can I make Rails.cache.fetch ONLY EXPIRE the cache if the fetch_json returns valid data? However the cache should expire after 10 minutes if it receives new valid data.
This is how I tried to do it, but it does not work. Better Code highlighting in this Gist: https://gist.github.com/i42n/6094528
Any tips how I can get this work?
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