1
0
Fork 0
forked from OpenNeo/impress
impress/app/services/owls_value_guide.rb
Emi Matchu 6d343989de Extend OWLS caching from 15 minutes to 1 day
Poking at the site, I didn't love that clicking any of the NC items on
the homepage took a few seconds to load cuz of the OWLS request taking
a couple seconds.

If the request were faster to load I might decide otherwise, but for
now, let's just keep that cache long.

Another approach we could take would be to ask for an endpoint that
returns all the values at once, so we could cache and update them all
together, instead of having it all split into separate cache keys!
2024-01-15 06:19:48 -08:00

75 lines
1.9 KiB
Ruby

module OwlsValueGuide
include HTTParty
ITEMDATA_URL_TEMPLATE = Addressable::Template.new(
"https://neo-owls.net/itemdata/{item_name}"
)
def self.find_by_name(item_name)
# Load the itemdata, pulling from the Rails cache if possible.
cache_key = "OwlsValueGuide/itemdata/#{item_name}"
data = Rails.cache.fetch(cache_key, expires_in: 1.day) do
load_itemdata(item_name)
end
if data == :not_found
raise NotFound
end
# Owls has records of some items that it explicitly marks as having no
# listed value. We don't care about that distinction, just return nil!
return nil if data['owls_value'].blank?
Value.new(data['owls_value'], parse_last_updated(data['last_updated']))
end
Value = Struct.new(:value_text, :updated_at)
class Error < StandardError;end
class NetworkError < Error;end
class NotFound < Error;end
private
def self.load_itemdata(item_name)
Rails.logger.info "[OwlsValueGuide] Loading value for #{item_name.inspect}"
url = ITEMDATA_URL_TEMPLATE.expand(item_name: item_name)
begin
res = get(url)
rescue StandardError => error
raise NetworkError, "Couldn't connect to Owls: #{error.message}"
end
if res.code == 404
# Instead of raising immediately, return `:not_found` to save this
# result in the cache, then raise *after* we exit the cache block. That
# way, we won't make repeat requests for items we have that Owls
# doesn't.
return :not_found
end
if res.code != 200
raise NetworkError, "Owls returned status code #{res.code} (expected 200)"
end
begin
res.parsed_response
rescue HTTParty::Error => error
raise NetworkError, "Owls returned unsupported data format: #{error.message}"
end
end
def self.parse_last_updated(date_str)
return nil if date_str.blank?
begin
Date.strptime(date_str, '%Y-%m-%d')
rescue Date::Error
Rails.logger.error(
"[OwlsValueGuide] unexpected last_updated format: #{date_str.inspect}"
)
return nil
end
end
end