MongoStore

It’s ActiveSupport::Cache::MongoStore – a MongoDB-based provider for the standard Rails 2 or Rails 3 cache mechanism. With an emphasis on fast writes and a memory-mapped architecture, Mongo is well-suited to caching. This gem aims to give you what the ubiquitous MemCacheStore does, but with Mongo’s persistence. (And without having to put a second RAM devourer in an environment already running Mongo.)

Getting Started

The only prerequisites are ActiveSupport and the mongo gem. If your app uses MongoMapper we can detect it and use the same database connection, but we don’t require it.

$ gem install mongo_store   # or 'sudo' as required

In your Rails application, just configure your config/environments/production.rb (and/or staging.rb and any other environment you want to cache) like so:

config.cache_store = :mongo_store

This default behavior creates a collection called rails_cache in either the Mongo database referenced by MongoMapper.database (if you’re using MM) or a database also called rails_cache. You can override these:

config.cache_store = :mongo_store, "foo"  # Collection name is "foo"
config.cache_store = :mongo_store, "foo", :db => "bar"  # DB name is "bar"

# You can pass a DB object instead of a database name...
deebee = Mongo::DB.new("bar", Mongo::Connection.new)
config.cache_store = :mongo_store, "foo", :db => deebee

# Or just pass in a Collection object and you're covered...
collie = Mongo::Collection.new(deebee, "foo")
config.cache_store = :mongo_store, collie

We don’t have a separate option for connecting to a different server. If you don’t intend to use localhost, make a new Mongo::Collection or Mongo::DB object from a different connection.

Options

The following hash options are recognized on initialization:

Other Goodness

MongoStore is a drop-in caching store and doesn’t require any special treatment. The only extra behavior on top of what you get from ActiveSupport::Cache::Store is as follows:

:expires_in option on the #write method

This was built into all stores in Rails 3. In Rails 2, we implement it with same behavior as the option in MemCacheStore. Specify a number of seconds or an ActiveSupport helper equivalent, e.g.: :expires_in => 5.minutes. Keys past their expiration date are not returned on reads.

NOTE: This behavior is fairly dumb and uses Time.now on the application side. If you have a number of app servers hitting one database and their times aren’t in sync, expect unwarranted cache misses.

#clean_expired method

If the collection size starts to explode from old cached values that are never being written again, you can set up a delayed job or Rake task to run Rails.cache.clean_expired every few weeks or such. Cached values that are reused are updated in place, so running this too frequently may actually impair performance.

#clear method

Empties the cache. The moral equivalent of Rails.cache.delete_matched(/.*/) but faster.

Limitations

Support

You can find the docs here: http://rdoc.info/projects/SFEley/mongo_store/

Other than that, there is no email list, forum, wiki, Google Wave, or international convention for this gem. Come on. It’s a hundred lines of code.

Contributing

Please leave an issue. Or fork, fix, and pull-request. Or send me an email (sfeley@gmail.com). Or buy me a whisky at the hotel bar. (Single malt only, please.)

You can also check out my podcast if you like science fiction stories.

And Have Fun.

License

This project is licensed under the Don’t Be a Dick License, version 0.2, and is copyright 2010 by Stephen Eley. See the LICENSE.markdown file for elaboration on not being a dick. (But you probably already know.)