Răsfoiți Sursa

Add cache to stats

poeti8 7 ani în urmă
părinte
comite
5758e3cc39
3 a modificat fișierele cu 24 adăugiri și 1 ștergeri
  1. 6 1
      server/controllers/urlController.js
  2. 1 0
      server/db/url.js
  3. 17 0
      server/utils/index.js

+ 6 - 1
server/controllers/urlController.js

@@ -27,7 +27,7 @@ const {
 } = require('../db/url');
 const transporter = require('../mail/mail');
 const redis = require('../redis');
-const { addProtocol, generateShortUrl } = require('../utils');
+const { addProtocol, generateShortUrl, getStatsCacheTime } = require('../utils');
 const config = require('../config');
 
 const dnsLookup = promisify(dns.lookup);
@@ -251,8 +251,13 @@ exports.deleteUrl = async ({ body: { id, domain }, user }, res) => {
 exports.getStats = async ({ query: { id, domain }, user }, res) => {
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
   const customDomain = domain !== config.DEFAULT_DOMAIN && domain;
+  const redisKey = id + (customDomain || '') + user.email;
+  const cached = await redis.get(redisKey);
+  if (cached) return res.status(200).json(JSON.parse(cached));
   const stats = await getStats({ id, domain: customDomain, user });
   if (!stats) return res.status(400).json({ error: 'Could not get the short URL stats.' });
+  const cacheTime = getStatsCacheTime(stats.total);
+  redis.set(redisKey, JSON.stringify(stats), 'EX', cacheTime);
   return res.status(200).json(stats);
 };
 

+ 1 - 0
server/db/url.js

@@ -407,6 +407,7 @@ exports.getStats = ({ id, domain, user }) =>
             domain ? records[0].get('domain') : config.DEFAULT_DOMAIN
           }/${id}`,
           target: records[0].get('l').properties.target,
+          updatedAt: new Date().toISOString(),
           lastDay: stats[0],
           lastWeek: stats[1],
           lastMonth: stats[2],

+ 17 - 0
server/utils/index.js

@@ -1,4 +1,5 @@
 const URL = require('url');
+const ms = require('ms');
 const config = require('../config');
 
 exports.addProtocol = url => {
@@ -10,3 +11,19 @@ exports.generateShortUrl = (id, domain) =>
   `http${!domain ? 's' : ''}://${domain || config.DEFAULT_DOMAIN}/${id}`;
 
 exports.isAdmin = email => config.ADMIN_EMAILS.includes(email);
+
+exports.getStatsCacheTime = total => {
+  switch (true) {
+    case total > 5000 && total < 20000:
+      return ms('1 hour');
+
+    case total < 40000:
+      return ms('3 hours');
+
+    case total > 40000:
+      return ms('6 hours');
+
+    default:
+      return ms('15 minutes');
+  }
+};