diff options
Diffstat (limited to 'server/middlewares')
-rw-r--r-- | server/middlewares/cache.ts | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts index 1e5a13b2e..c671b88c9 100644 --- a/server/middlewares/cache.ts +++ b/server/middlewares/cache.ts | |||
@@ -6,59 +6,60 @@ import { logger } from '../helpers/logger' | |||
6 | 6 | ||
7 | const lock = new AsyncLock({ timeout: 5000 }) | 7 | const lock = new AsyncLock({ timeout: 5000 }) |
8 | 8 | ||
9 | function cacheRoute (lifetime: number) { | 9 | function cacheRoute (lifetimeArg: string | number) { |
10 | return async function (req: express.Request, res: express.Response, next: express.NextFunction) { | 10 | return async function (req: express.Request, res: express.Response, next: express.NextFunction) { |
11 | const redisKey = Redis.Instance.buildCachedRouteKey(req) | 11 | const redisKey = Redis.Instance.buildCachedRouteKey(req) |
12 | 12 | ||
13 | await lock.acquire(redisKey, async (done) => { | 13 | try { |
14 | const cached = await Redis.Instance.getCachedRoute(req) | 14 | await lock.acquire(redisKey, async (done) => { |
15 | const cached = await Redis.Instance.getCachedRoute(req) | ||
15 | 16 | ||
16 | // Not cached | 17 | // Not cached |
17 | if (!cached) { | 18 | if (!cached) { |
18 | logger.debug('No cached results for route %s.', req.originalUrl) | 19 | logger.debug('No cached results for route %s.', req.originalUrl) |
19 | 20 | ||
20 | const sendSave = res.send.bind(res) | 21 | const sendSave = res.send.bind(res) |
21 | 22 | ||
22 | res.send = (body) => { | 23 | res.send = (body) => { |
23 | if (res.statusCode >= 200 && res.statusCode < 400) { | 24 | if (res.statusCode >= 200 && res.statusCode < 400) { |
24 | const contentType = res.get('content-type') | 25 | const contentType = res.get('content-type') |
25 | Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode) | 26 | const lifetime = parseDuration(lifetimeArg) |
26 | .then(() => done()) | 27 | |
27 | .catch(err => { | 28 | Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode) |
28 | logger.error('Cannot cache route.', { err }) | 29 | .then(() => done()) |
29 | return done(err) | 30 | .catch(err => { |
30 | }) | 31 | logger.error('Cannot cache route.', { err }) |
32 | return done(err) | ||
33 | }) | ||
34 | } | ||
35 | |||
36 | return sendSave(body) | ||
31 | } | 37 | } |
32 | 38 | ||
33 | return sendSave(body) | 39 | return next() |
34 | } | 40 | } |
35 | 41 | ||
36 | return next() | 42 | if (cached.contentType) res.set('content-type', cached.contentType) |
37 | } | ||
38 | |||
39 | if (cached.contentType) res.set('content-type', cached.contentType) | ||
40 | 43 | ||
41 | if (cached.statusCode) { | 44 | if (cached.statusCode) { |
42 | const statusCode = parseInt(cached.statusCode, 10) | 45 | const statusCode = parseInt(cached.statusCode, 10) |
43 | if (!isNaN(statusCode)) res.status(statusCode) | 46 | if (!isNaN(statusCode)) res.status(statusCode) |
44 | } | 47 | } |
45 | 48 | ||
46 | logger.debug('Use cached result for %s.', req.originalUrl) | 49 | logger.debug('Use cached result for %s.', req.originalUrl) |
47 | res.send(cached.body).end() | 50 | res.send(cached.body).end() |
48 | 51 | ||
49 | return done() | 52 | return done() |
50 | }) | 53 | }) |
54 | } catch (err) { | ||
55 | logger.error('Cannot serve cached route.', err) | ||
56 | return next() | ||
57 | } | ||
51 | } | 58 | } |
52 | } | 59 | } |
53 | 60 | ||
54 | const cache = (duration: number | string) => { | ||
55 | const _lifetime = parseDuration(duration, 3600000) | ||
56 | return cacheRoute(_lifetime) | ||
57 | } | ||
58 | |||
59 | // --------------------------------------------------------------------------- | 61 | // --------------------------------------------------------------------------- |
60 | 62 | ||
61 | export { | 63 | export { |
62 | cacheRoute, | 64 | cacheRoute |
63 | cache | ||
64 | } | 65 | } |