Skip to content

Instantly share code, notes, and snippets.

@neovintage
Created November 6, 2010 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neovintage/665714 to your computer and use it in GitHub Desktop.
Save neovintage/665714 to your computer and use it in GitHub Desktop.
A cache store for MongoDB that uses capped collections
require 'mongo'
require 'rails'
module Rails
class << self
def fifo_cache
FIFO_CACHE
end
end
end
module MongoFifo
class Railtie < Rails::Railtie
initializer "mongo_fifo.configure_mongodb_connection" do |app|
unless defined?(FIFO_CACHE)
silence_warnings { Object.const_set "FIFO_CACHE", app.config.mongo_fifo }
end
end
end
# Some of the code taken from John Nunemaker's bin gem
# http://github.com/jnunemaker/bin
#
class Store
attr_reader :options
# Assumes that the user of this code will create connection to
# MongoDB
#
def initialize (collection, options = {})
@collection, @options = collection['cache'], options
end
def expires_in
@expires_in ||= options[:expires_in] || 1.week
end
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned. Otherwise,
# nil is returned.
#
def read(name, options = {})
search_options = { :_id => name, :expires_at => {'$gt' => Time.now.utc} }
if doc = @collection.find_one(search_options.merge(options))
Marshal.load(doc['value'].to_s)
end
end
# Writes the value to the cache, with the key.
#
def write(name, value, options = {})
name = name.to_s
expires = Time.now.utc + ((options && options[:expires_in]) || expires_in)
value = BSON::Binary.new(Marshal.dump(value))
doc = {:_id => name, :value => value, :expires_at => expires}
@collection.save(doc)
end
# Return true if the cache contains an entry for the given key.
#
def exist?(name, options = nil)
result = read(name, options)
if result && (result[:expires_at] > Time.now.utc)
true
else
false
end
end
# Removes all documents from the collection
#
def clear(options = {})
@collection.remove(options)
end
private
def log(operation, key, options = nil)
return unless logger && logger.debug? && !silence?
logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment