2

私のアプリは、過去の気象データの取得など、多くのページ スクレイピングを行います。特定のページをフェッチしたら、それを PostgreSQL データベースにキャッシュして、その特定のリクエストのためにリモート サーバーに再度アクセスする必要がないようにします。

履歴データは決して変更されないため、それらを「永久に」キャッシュしたいと考えています。これには、キャッシュされたページをデータベースなどの長期的な永続ストアに保存する必要があります。

Mechanize をラップする初歩的なキャッシュ メカニズムを作成しました。それは機能しますが、私よりも優れたコーディング技術を持つ誰かがすでにこれを実装している可能性が高いようです.

すでにこれを行っている宝石やライブラリはありますか?

4

4 に答える 4

1

だから私は考え、考え、そして Mechanize と VCR のソース コードを見て、私は本当に問題を考えすぎているだけだと判断しました。以下は私のニーズにぴったりです。(私は DataMapper を使用していますが、それを ActiveRecord モデルに変換するのは簡単です):

class WebCache
  include DataMapper::Resource

  property :id, Serial
  property :serialized_key, Text
  property :serialized_value, Text
  property :created_at, DateTime
  property :updated_at, DateTime

  def with_db_cache(akey)
    serialized_key = YAML.dump(akey)
    if (r = self.all(:serialized_key => serialized_key)).count != 0
      # cache hit: return the de-serialized value
      YAML.load(r.first.serialized_value)
    else
      # cache miss: evaluate the block, serialize and cache the result
      yield(akey).tap {|avalue| 
        self.create(:serialized_key => serialized_key, 
                    :serialized_value => YAML.dump(avalue))
      }
    end
  end
end

使用例:

def fetch(uri)
  WebCache.with_db_cache(uri) {|uri| 
    # arrive here only on cache miss
    Net::HTTP.get_response(URI(uri))
  }
end

解説

私は以前、適切な Web キャッシング スキームは、Cache-Control、If-Modified-Since などのヘッダー フィールドを観察して尊重し、タイムアウトやその他の Web 病理を自動的に処理すると信じていました。しかし、実際の Web ページを調べたところ、真に静的なデータは頻繁に短いキャッシュ時間でマークされていることが明らかになりました。したがって、何かをキャッシュする期間と、失敗したクエリをいつ再試行するかを呼び出し元に決定させる方が理にかなっています。

その時点で、コードは非常に単純になりました。

道徳:あなたの問題について考えすぎないでください。

于 2013-02-13T06:13:01.790 に答える
0

Open-URI-CacheまたはFaraday-HTTP-Cacheを見ることができます。最初のものは、必要なものに近いかもしれません。どちらもデータベースにログを記録しませんが、独自のストレージ レイヤーを作成できる可能性があります。Heroku の経験はありませんが、ファイル システムはこの種のキャッシュに適した場所のようです。

于 2014-09-25T12:30:53.473 に答える
0

たぶん、squidのようなプロキシ キャッシュを使用する必要があります。自分でやろうとするよりも速く、簡単で、信頼性が高くなります。

于 2013-02-10T21:19:17.640 に答える
0

ビデオデッキはおそらくあなたが望むものです。

于 2013-02-10T20:35:25.800 に答える