Engine Caching

lmjabreu edited this page Sep 15, 2012 · 2 revisions

Resourceful comes with a helper for managing an in-memory cache of your documents. This helps increase the speed of resourceful by avoiding extraneous interactions with the back-end.

Unlike engines, caches have a completely synchronous API. This is acceptable since the calls are short and usually occur inside an asynchronously-executing procedure.

Cache Constructor

This creates a new in-memory cache for your engine. The cache is automatically populated by resourceful. This means that you don't need to actually use the cache directly for many operations. In fact, the memory engine doesn't explicitly use resourceful.Cache at all.

var resourceful = require('resourceful');

var cache = new resourceful.Cache();

Cache Instance Methods

resourceful.Cache has the following prototypes for interacting with the in-memory cache:

  • Cache.prototype.get(id): Attempt to 'get' a cached document.
  • Cache.prototype.put(id, doc): Attempt to 'put' a document into the cache.
  • Cache.prototype.update(id, doc): Attempt to update a document in the cache. This means that it will attempt to merge your old and new document instead of overwriting the old with the new!
  • Cache.prototype.clear(id): Attempts to remove a document from the cache. Document 'overwriting' may be achieved with call to .clear followed by a call to .put.
  • Cache.prototype.has(id): Checks to see if a given document is in the cache or not.

The couchdb engine explicity uses resourceful.Cache in two places, both in cases where fetching the document is prohibitive and can be avoided. The couchdb engine checks the cache for the object with which to merge new data before uploading:

Couchdb.prototype.update = function (id, doc, callback) {

  return this.cache.has(id) 
    ? this.put(id, resourceful.mixin({}, this.cache.get(id).toJSON(), doc), callback)
    : this.request('merge', id, doc, callback);
};

object.toJSON is a misnomer; Instead of returning json, .toJSON() returns a cloned object. This method is named as such because it's detected and used by JSON.stringify.

The couchdb engine checks the cache for the object it wants to destroy:

if (this.cache.has(id)) {

  args.splice(1, -1, this.cache.get(id)._rev);
  return this.request.apply(this, ['remove'].concat(args));
}

In the above snippet (just a small part of the entire function), the couchdb engine uses the cache to get revision data without doing a GET.