diff --git a/examples/autoexpire_cache.rb b/examples/autoexpire_cache.rb index ced862b3d875a81bf701d4dc5356e3587382371a..beca293ec6c45495b88c3e8837ea0d2bfdd453e8 100644 --- a/examples/autoexpire_cache.rb +++ b/examples/autoexpire_cache.rb @@ -1,10 +1,18 @@ -# This class implements a cache with simple delegation to the Redis store, but -# when it creates a key/value pair, it also sends an EXPIRE command with a TTL. -# It should be fairly simple to do the same thing with Memcached. +# This class implements a common cache interface with simple delegation to the chosen cache store. + +require 'dalli_client' +require 'redis_client' + class AutoexpireCache - def initialize(store) - @store = store - @ttl = 86400 + def initialize(store_type = :redis, ttl = 86400) + @store = case store_type + when :redis + RedisClient.new(ttl) + when :dalli + DalliClient.new(ttl) + else + raise 'Unknown client type' + end end def [](url) @@ -13,7 +21,6 @@ class AutoexpireCache def []=(url, value) @store.[]=(url, value) - @store.expire(url, @ttl) end def keys @@ -25,4 +32,4 @@ class AutoexpireCache end end -Geocoder.configure(:cache => AutoexpireCache.new(Redis.new)) +Geocoder.configure(:cache => AutoexpireCache.new) diff --git a/examples/dalli_client.rb b/examples/dalli_client.rb new file mode 100644 index 0000000000000000000000000000000000000000..eb3e5a8eed46c80d3edd1d2d9dfb039817aa688c --- /dev/null +++ b/examples/dalli_client.rb @@ -0,0 +1,58 @@ +# gem install dalli + +require 'dalli/client' +require 'yaml' + +class DalliClient + # Setup Dalli as on Heroku using the Memcachier gem. + # On other setups you'll have to specify your Memcached server + def initialize(ttl = 86400) + @keys = 'GeocoderDalliClientKeys' + @store = Dalli::Client.new(:expires_in => ttl) + end + + def [](key) + res = @store.get(key) + res = YAML::load(res) if res.present? + res + end + + def []=(key, value) + if value.nil? + del(key) + else + key_cache_add(key) if @store.add(key, YAML::dump(value)) + end + value + end + + def keys + key_cache + end + + def del(key) + key_cache_delete(key) if @store.delete(key) + end + + private + + def key_cache + the_keys = @store.get(@keys) + if the_keys.nil? + @store.add(@keys, YAML::dump([])) + [] + else + YAML::load(the_keys) + end + end + + def key_cache_add(key) + @store.replace(@keys, YAML::dump(key_cache << key)) + end + + def key_cache_delete(key) + tmp = key_cache + tmp.delete(key) + @store.replace(@keys, YAML::dump(tmp)) + end +end diff --git a/examples/redis_client.rb b/examples/redis_client.rb new file mode 100644 index 0000000000000000000000000000000000000000..abb8aa7b2ab8d7e81005c1bd9f3d41f9c158ad19 --- /dev/null +++ b/examples/redis_client.rb @@ -0,0 +1,26 @@ +# This class implements a cache with simple delegation to the Redis store, but +# when it creates a key/value pair, it also sends an EXPIRE command with a TTL. +# It should be fairly simple to do the same thing with Memcached. +class RedisClient + def initialize(ttl = 86400) + @store = Redis.new + @ttl = ttl + end + + def [](url) + @store.[](url) + end + + def []=(url, value) + @store.[]=(url, value) + @store.expire(url, @ttl) + end + + def keys + @store.keys + end + + def del(url) + @store.del(url) + end +end \ No newline at end of file