Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

What’s the Point?

So after my announcement about moneta yesterday, a very common question was “what’s the point of this?”

There are basically two targets:

  • If you are needing a cache store that might potentially need to scale, you can use Moneta::Memory to start, and then scale up to Moneta::Memcache or Moneta::TokyoCabinet, etc. It’s certainly possible to do that right now, but you’d have to retool some of your code in order to do that. With Moneta, key/value stores are literally just drop-in-replacements for each other.
  • More interestingly, libraries that want to provide sugar around key/value stores (e.g. Rails and Merb’s caching support) can use Moneta as their backend in much the same way as they use Rack to connect to web servers or use DataObjects to connect to backend databases. By providing a simple API, libraries can say “we support moneta stores”, and then any stores created by the community will just work. One interesting ideas that I heard from dkubb last night was moving DataMapper’s IdentityMap to be compatible with Moneta (pretty darn easy since Moneta’s API is a subset of the Hash API), and support plugging in other moneta stores. This would allow processes or even multiple servers to share an IdentityMap, providing a simple write-through cache. When potentially combined with something like Memcache, this could be a powerful combination.
  • The bottom line is that by making key/value stores an abstracted idea, the community can build a slew of stores for Moneta, which will then work with whatever front-ends use them. The simplicity of the idea belies the potential power that comes from creating easy to understand APIs and letting the community at large take care of the actual implementaion.

6 Responses to “What’s the Point?”

Why not add a #fetch method? Both Rails & Merb’s caching implementation have a fetch method.

Whoops… I forgot to include it in the original description of the API. Moneta has fetch, but it behaves like Ruby’s #fetch (i.e. doesn’t store the value)

The target with DataMapper’s IdentityMap for the next minor release was using a subset of the Hash API anyway. When Yehuda showed me his moneta API, I realized we could use a moneta store as an I — with no code changes to DataMapper or Moneta whatsoever.

I love it when libraries base their API conventions on Ruby core classes.

Whoops.. I meant to say: “When Yehuda showed me his moneta API, I realized we could use a moneta store as an *IM* — with no code changes to DataMapper or Moneta whatsoever.”

IM == IdentityMap, which is something DataMapper uses internally to cache objects by their key in memory. When you use Model#get, DM checks the IM to see if you’ve already retrieved the object, and if so, just pulls it from there, saving you a call to the backend. This behavior only happens inside a repository() block, so it’s opt-in only, but extremely useful.

Originally the plan was to make some DataMapper::IdentityMap plugins for Memcache and Tokyo Cabinet, but I might just tell people to use a store that is Moneta-compatible instead. The advantage to this approach is that a Moneta store isn’t DM-only, you could conceivably use it as a key/value cache for merb-cache, Rack::Cache or ActiveRecord among other things.

Moneta looks great! Have you considered supporting the memcached gem libmemcached library in addition to the memcache-client gem? From what I read this combination has better performance at the cost of being slightly harder to install since it has to compile.

Love it. Rack for key/value stores!

Leave a Reply