2017-05-08 8 views
4

나는 캐시에 외부 서비스에서 환율의 수를 가져오고이를 저장하기 위해 노력하고 있어요 :Open-Uri에서 외부 서비스 오류를 처리하는 방법은 무엇입니까? 내 레일 응용 프로그램에서

require 'open-uri' 

module ExchangeRate 

    def self.all 
    Rails.cache.fetch("exchange_rates", :expires_in => 24.hours) { load_all } 
    end 

    private 

    def self.load_all 
     hashes = {} 
     CURRENCIES.each do |currency| 
     begin 
      hash = JSON.parse(open(URI("http://api.fixer.io/latest?base=#{currency}")).read) #what if not available? 
      hashes[currency] = hash["rates"] 
     rescue Timeout::Error 
      puts "Timeout" 
     rescue OpenURI::Error => e 
      puts e.message 
     end 
     end 
     hashes 
    end 

end 

이 개발에서 잘 작동하지만 생산 환경에 대한 걱정. 외부 서비스를 사용할 수없는 경우 어떻게 캐싱되지 않도록 할 수 있습니까? ExchangeRate.all은 오래되었지만 외부 서비스 오류로 인해 업데이트 할 수없는 경우에도 항상 데이터가 포함되도록하려면 어떻게해야합니까?

몇 가지 기본적인 오류 처리를 추가하려고했지만 충분하지 않습니다.

+1

예를 들어 "exchange_rates_backup"의 다른 캐시는 만료되지 않고 외부 서비스가 성공적으로 읽힐 때마다 설정 될 수 있습니다. 그런 다음이 "백업"캐시가 백업으로'all' 메소드에서 사용될 수 있습니다. – BoraMa

+0

데이터베이스 내에서 사용자 정의 테이블을 사용할 수 있습니다. 'load_all'이 실패하면, 자신의 테이블에있는 레코드를 사용할 수 있습니다. – etagwerker

답변

0

외부 서비스가 24 시간마다 캐싱을 유지할만큼 충분히 안정적이지 않다고 걱정되는 경우 자동 캐시 만료를 사용 중지하고 사용자가 이전 데이터로 작업하도록하고 일종의 알림 시스템을 설정해야합니다 load_all이 실패하면 알려줍니다.

  1. 이 ExchangeRate.all 항상 만기와 캐시 된 복사본을 반환 가정하자 (이 nil을 반환을 더 캐시가 발견되지 않는 경우) : 여기

    내가 할 줄거야

    module ExchangeRate 
        def self.all 
        rates = Rails.cache.fetch("exchange_rates") 
        UpdateCurrenciesJob.perform_later if rates.nil? 
        rates 
        end 
    end 
    
  2. 업데이트를 정기적으로 처리하는 ActiveJob을 만듭니다.

    class UpdateCurrenciesJob < ApplicationJob 
        queue_as :default 
    
        def perform(*_args) 
        hashes = {} 
        CURRENCIES.each do |currency| 
         begin 
         hash = JSON.parse(open(URI("http://api.fixer.io/latest?base=#{currency}")).read) # what if not available? 
         hashes[currency] = hash['rates'].merge('updated_at' => Time.current) 
         rescue Timeout::Error 
         puts 'Timeout' 
         rescue OpenURI::Error => e 
         puts e.message 
         end 
    
         if hashes[currency].blank? || hashes[currency]['updated_at'] < Time.current - 24.hours 
         # send a mail saying "this currency hasn't been updated" 
         end 
        end 
    
        Rails.cache.write('exchange_rates', hashes) 
        end 
    end 
    
  3. 몇 시간마다 실행되도록 작업을 설정하십시오 (4, 8, 12, 24 미만). 이렇게하면 통화가 백그라운드에서로드되고 클라이언트는 항상 데이터를 보유하게되므로 통화가 작동하지 않는지 항상 알 수 있습니다.