[Groonga-commit] droonga/express-droonga at a1ab785 [master] Implement basic cache system based on uber-cache

Back to archive index

YUKI Hiroshi null+****@clear*****
Thu Mar 20 14:07:51 JST 2014


YUKI Hiroshi	2014-03-20 14:07:51 +0900 (Thu, 20 Mar 2014)

  New Revision: a1ab78555c6d19b9f31fe1fa50b3c3264abc5e55
  https://github.com/droonga/express-droonga/commit/a1ab78555c6d19b9f31fe1fa50b3c3264abc5e55

  Message:
    Implement basic cache system based on uber-cache

  Modified files:
    lib/response-cache.js
    package.json

  Modified: lib/response-cache.js (+83 -6)
===================================================================
--- lib/response-cache.js    2014-03-20 12:39:35 +0900 (caf3d46)
+++ lib/response-cache.js    2014-03-20 14:07:51 +0900 (12ab9e7)
@@ -1,16 +1,93 @@
+var createCache = require('uber-cache');
+
+function generateKey(request) {
+  return request.method + '\n' + request.url;
+}
+
+function sendCachedResponse(response, cached) {
+  response.statusCode = cached.status;
+  Object.keys(cached.headers).forEach(function(key) {
+    response.setHeader(key, cached.headers[key]);
+  });
+  cached.body.forEach(function(chunk) {
+    response.write(chunk.data, chunk.encoding);
+  });
+  response.end();
+}
+
+function ResponseCacheEntry(cache) {
+  this.data = {
+    status:  0,
+    headers: {},
+    body:    []
+  };
+}
+ResponseCacheEntry.prototype = {
+  get cachable() {
+    return this.data.status == 200;
+  },
+  write: function(chunk, encoding) {
+    this.data.body.push({
+      data:     chunk,
+      encoding: encoding
+    });
+  },
+  finalize: function(response) {
+    this.data.status = response.statusCode;
+    this.data.headers = response.headers;
+  }
+};
+
 exports = module.exports = function(options) {
   options = options || {};
 
+  var size = options.size || 100;
+  var ttlInSeconds = options.ttl || options.ttlInSeconds || 60;
+  var ttlInMilliSeconds = options.ttlInMilliSeconds || (ttlInSeconds * 1000);
+
+  var cache = createCache({
+    size: size
+  });
+
   return function(request, response, next) {
+    if (request.method != 'GET') {
+      next();
+      return;
+    }
+
     var originalWrite = response.write;
     var originalEnd = response.end;
 
-    response.write = function(chunk, encoding) {
-      return originalWrite.call(response, chunk, encoding);
-    };
+    var cacheKey = generateKey(request);
+    cache.get(cacheKey, function(error, cachedResponse) {
+      if (error) {
+        console.error(error);
+        return;
+      }
+
+      if (cachedResponse) {
+        sendCachedResponse(response, cachedResponse);
+        return;
+      }
+
+      var entry = new ResponseCacheEntry();
+
+      response.write = function(chunk, encoding) {
+        entry.write(chunk, encoding);
+        return originalWrite.call(response, chunk, encoding);
+      };
+
+      response.end = function(chunk, encoding) {
+        entry.write(chunk, encoding);
+        var returnValue = originalEnd.call(response, chunk, encoding);
+
+        entry.finalize(response);
+        if (entry.cachable) {
+          cache.set(cacheKey, entry.data, ttlInMilliSeconds);
+        }
 
-    response.end = function(chunk, encoding) {
-      return originalEnd.call(response, chunk, encoding);
-    };
+        return returnValue;
+      };
+    });
   };
 };

  Modified: package.json (+1 -0)
===================================================================
--- package.json    2014-03-20 12:39:35 +0900 (ea7bbbe)
+++ package.json    2014-03-20 14:07:51 +0900 (1ccb62a)
@@ -24,6 +24,7 @@
     "inflection": "*",
     "jade": "*",
     "less-middleware": ">=0.2",
+    "uber-cache": "*",
     "msgpack": "*",
     "socket.io": "*",
     "commander": "*"
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index