在我的Rails应用程序中,我有一个非常昂贵的函数,每天从外部服务获取一堆转换率:
require 'open-uri'
module Currency
def self.all
@all ||= fetch_all
end
def self.get_rate(from_curr = "EUR", to_curr = "USD")
all[from_curr][to_curr]
end
private
def self.fetch_all
hashes = {}
CURRENCIES.keys.each do |currency|
hash = JSON.parse(open(URI("http://api.fixer.io/latest?base=#{currency}")).read)
hashes[currency] = hash["rates"]
end
hashes
end
end
有没有办法存储这个函数的结果(哈希)来加快速度?现在,我正在尝试将它存储在一个实例变量@all
中,这会加快它的速度,但它不会在请求之间保持不变。如何在请求中保留它?
答案 0 :(得分:3)
使用以下代码在初始值设定项中创建一个文件currency_rates.rb
:
require 'open-uri'
hashes = {}
CURRENCIES.keys.each do |currency|
hashes[currency] = JSON.parse(open(URI("http://api.fixer.io/latest?base=#{currency}")).read)["rates"]
end
CURRENCY_RATES = hashes
然后编写以下每日运行的rake任务:
task update_currency_rates: :environment do
require 'open-uri'
hashes = {}
CURRENCIES.keys.each do |currency|
hashes[currency] = JSON.parse(open(URI("http://api.fixer.io/latest?base=#{currency}")).read)["rates"]
end
Constant.const_set('CURRENCY_RATES', hashes)
end
唯一的缺点是,每次部署新版本的app /重启时都会运行它。如果你对它好的话你可以使用它。
如果您使用memcachier
之类的缓存,那么您可以避免这种情况,那么您可以这样做,
def currency_rates
Rails.cache.fetch('currency_rates', expires_in: 24.hours) do
# write above code in some method and call here which will return hash and thus it will be cached.
end
end