From 2da7dfe888d34884b8168b2c9f449f555d38c77b Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Tue, 15 Mar 2011 22:47:50 -0400 Subject: [PATCH] Refactor: add Geocoder::Cache class. This allows us to add a method for expiring cache keys and generally gives us more control over the cache interface. --- lib/geocoder.rb | 1 + lib/geocoder/cache.rb | 81 ++++++++++++++++++++++++++++++++++++ lib/geocoder/lookups/base.rb | 27 +++--------- 3 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 lib/geocoder/cache.rb diff --git a/lib/geocoder.rb b/lib/geocoder.rb index 22f14105..594f3df8 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -1,5 +1,6 @@ require "geocoder/configuration" require "geocoder/calculations" +require "geocoder/cache" require "geocoder/railtie" require "geocoder/request" diff --git a/lib/geocoder/cache.rb b/lib/geocoder/cache.rb new file mode 100644 index 00000000..82d47d09 --- /dev/null +++ b/lib/geocoder/cache.rb @@ -0,0 +1,81 @@ +module Geocoder + + ## + # The working Cache object, or +nil+ if none configured. + # + def self.cache + if @cache.nil? and store = Geocoder::Configuration.cache + @cache = Cache.new(store, Geocoder::Configuration.cache_prefix) + end + @cache + end + + class Cache + + def initialize(store, prefix) + @store = store + @prefix = prefix + end + + ## + # Read from the Cache. + # + def [](url) + interpret store[key_for(url)] + end + + ## + # Write to the Cache. + # + def []=(url, value) + store[key_for(url)] = value + end + + ## + # Expire cache entry for given URL, + # or pass <tt>:all</tt> to expire everything. + # + def expire(url) + if url == :all + urls.each{ |u| expire(u) } + else + self[url] = nil + end + end + + + private # ---------------------------------------------------------------- + + attr_reader :prefix, :store + + ## + # Cache key for a given URL. + # + def key_for(url) + [prefix, url].join + end + + ## + # Array of keys with the currently configured prefix + # that have non-nil values. + # + def keys + store.keys.select{ |k| k.match /^#{prefix}/ and interpret(store[k]) } + end + + ## + # Array of cached URLs. + # + def urls + keys.map{ |k| k[/^#{prefix}(.*)/, 1] } + end + + ## + # Clean up value before returning. Namely, convert empty string to nil. + # (Some key/value stores return empty string instead of nil.) + # + def interpret(value) + value == "" ? nil : value + end + end +end diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 65ff2128..90c17a30 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -60,7 +60,7 @@ module Geocoder rescue TimeoutError warn "Geocoding API not responding fast enough " + "(see Geocoder::Configuration.timeout to set limit)." - end + end end ## @@ -82,13 +82,12 @@ module Geocoder # Fetches a raw search result (JSON string). # def fetch_raw_data(query, reverse = false) - url = query_url(query, reverse) - key = cache_key(url) timeout(Geocoder::Configuration.timeout) do - unless cache and (response = cache[key]) and response != "" + url = query_url(query, reverse) + unless cache and response = cache[url] response = Net::HTTP.get_response(URI.parse(url)).body if cache - cache[key] = response + cache[url] = response end end response @@ -96,24 +95,10 @@ module Geocoder end ## - # Cache key for a given URL. - # - def cache_key(url) - [cache_prefix, url].join - end - - ## - # The configured prefix for cache keys. - # - def cache_prefix - Geocoder::Configuration.cache_prefix || "geocoder:" - end - - ## - # The configured cache store. + # The working Cache object. # def cache - Geocoder::Configuration.cache + Geocoder.cache end ## -- GitLab