1

I'm trying to implement a cache system for a data-delivery tool for different clients with node.js. It's an http-service and I use express to handle the requests. My cache-system needs to support three cases:

Case 1 - There is no cache: The program receives the data via the given get-method. If successful it writes the cache.

Case 2 - There is a cache: The program receives the cache.

Case 3 - There is no cache but the get-method for the same request was already called by a different client and is currently being processed. The programm needs to wait until the other request received its data via the get-method and deliver the newly written cache.

I solved the problem of "Case 3" with events. I register an event for every client / request combination. But it feels not very elegant to register an open amount of events. Also the use of queues is not one of the best solutions.

4

1 回答 1

1

IMO you don't need events to implement your cache system, but I don't see how it could be implemented without queues.

Here is how I would implement the cache:

var cache = {};

function get(uri, cb) {
  var key = uri; // id of the resource, you might want to strip some URI parts
  var cacheEntry = cache[key];

  if (!cacheEntry)
    cache[key] = cacheEntry = {};

  if (cacheEntry.value) {
     // cache hit - return the cached value
     return process.nextTick(function() { cb(null, cacheEntry.value });
  }

  if (cacheEntry.waiting) {
     // another request is in progress - queue the callback
     cacheEntry.waiting.push(cb);
     return;
  }

  // we are the first client asking for this value
  cacheEntry.waiting = [cb];
  request.get(uri, handleResponse);


  function handleResponse(err, resp, body) {
    // process the response headers and body and save it to the cache
    var content = body;
    cacheEntry.value = content;

    // fire callbacks waiting for the cached value
    if (cacheEntry.waiting) {
      var q = cacheEntry.waiting;
      delete cacheEntry.waiting;
      q.forEach(function(cb) { cb(null, content); })
    }
  }
}
于 2013-08-19T09:34:53.730 回答