1 | var Eidetic = require('eidetic');
|
2 | var cacheStore = new Eidetic({
|
3 | maxSize: 50,
|
4 | canPutWhenFull: true
|
5 | });
|
6 |
|
7 | var queues = {};
|
8 | var redirects = {};
|
9 |
|
10 | module.exports.cacheSeconds = function(ttl) {
|
11 |
|
12 | return function(req, res, next) {
|
13 | var key = req.originalUrl;
|
14 | if (redirects[key]) return res.redirect(redirects[key]);
|
15 |
|
16 | var value = cacheStore.get(key);
|
17 |
|
18 | if (value) {
|
19 |
|
20 | if (value.isJson) {
|
21 | res.json(value.body);
|
22 | } else {
|
23 | res.send(value.body);
|
24 | }
|
25 | return;
|
26 | }
|
27 |
|
28 | res.original_send = res.send;
|
29 | res.original_json = res.json;
|
30 | res.original_redirect = res.redirect;
|
31 |
|
32 | if (!queues[key]) {
|
33 | queues[key] = [];
|
34 | }
|
35 |
|
36 |
|
37 | if (queues[key].length === 0
|
38 | && queues[key].push(function noop(){})) {
|
39 |
|
40 | var didHandle = false;
|
41 |
|
42 | function rawSend(data, isJson) {
|
43 | didHandle = true;
|
44 |
|
45 | var body = data instanceof Buffer ? data.toString() : data;
|
46 | if (res.statusCode < 400) cacheStore.put(key, { body: body, isJson: isJson }, ttl);
|
47 |
|
48 |
|
49 |
|
50 | var subscriber = null;
|
51 | while (subscriber = queues[key].shift()) {
|
52 | if (subscriber) {
|
53 | process.nextTick(subscriber);
|
54 | }
|
55 | }
|
56 |
|
57 | if (isJson) {
|
58 | res.original_json(body);
|
59 | } else {
|
60 | res.original_send(body);
|
61 | }
|
62 | }
|
63 |
|
64 | res.send = function (data) {
|
65 | if (didHandle) {
|
66 | res.original_send(data);
|
67 | } else {
|
68 | rawSend(data, false);
|
69 | }
|
70 | };
|
71 |
|
72 | res.json = function (data) {
|
73 | rawSend(data, true);
|
74 | };
|
75 |
|
76 |
|
77 |
|
78 | res.redirect = function(string) {
|
79 | var body = string instanceof Buffer ? string.toString() : string;
|
80 | redirects[key] = body;
|
81 | res.original_redirect(body);
|
82 | };
|
83 |
|
84 | next();
|
85 |
|
86 | } else {
|
87 | queues[key].push(function() {
|
88 | var value = cacheStore.get(key) || {};
|
89 | if (value.isJson) {
|
90 | res.json(value.body);
|
91 | } else {
|
92 | res.send(value.body);
|
93 | }
|
94 | });
|
95 | }
|
96 |
|
97 | }
|
98 |
|
99 | };
|
100 |
|
101 |
|
102 | module.exports.removeCache = function(url) {
|
103 | if (redirects[url])
|
104 | delete redirects[url];
|
105 | cacheStore.del(url);
|
106 | };
|
107 |
|
108 |
|
109 | module.exports.cacheStore = cacheStore;
|