aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/lib/job-queue/job-queue.ts2
-rw-r--r--server/lib/redis.ts12
-rw-r--r--server/middlewares/cache.ts73
3 files changed, 19 insertions, 68 deletions
diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts
index f09eb6ff1..3c810da98 100644
--- a/server/lib/job-queue/job-queue.ts
+++ b/server/lib/job-queue/job-queue.ts
@@ -71,7 +71,7 @@ class JobQueue {
71 this.jobRedisPrefix = 'bull-' + WEBSERVER.HOST 71 this.jobRedisPrefix = 'bull-' + WEBSERVER.HOST
72 const queueOptions = { 72 const queueOptions = {
73 prefix: this.jobRedisPrefix, 73 prefix: this.jobRedisPrefix,
74 redis: Redis.getRedisClient(), 74 redis: Redis.getRedisClientOptions(),
75 settings: { 75 settings: {
76 maxStalledCount: 10 // transcoding could be long, so jobs can often be interrupted by restarts 76 maxStalledCount: 10 // transcoding could be long, so jobs can often be interrupted by restarts
77 } 77 }
diff --git a/server/lib/redis.ts b/server/lib/redis.ts
index b4044bf0f..f77d0b62c 100644
--- a/server/lib/redis.ts
+++ b/server/lib/redis.ts
@@ -31,7 +31,7 @@ class Redis {
31 if (this.initialized === true) return 31 if (this.initialized === true) return
32 this.initialized = true 32 this.initialized = true
33 33
34 this.client = createClient(Redis.getRedisClient()) 34 this.client = createClient(Redis.getRedisClientOptions())
35 35
36 this.client.on('error', err => { 36 this.client.on('error', err => {
37 logger.error('Error in Redis client.', { err }) 37 logger.error('Error in Redis client.', { err })
@@ -45,7 +45,7 @@ class Redis {
45 this.prefix = 'redis-' + WEBSERVER.HOST + '-' 45 this.prefix = 'redis-' + WEBSERVER.HOST + '-'
46 } 46 }
47 47
48 static getRedisClient () { 48 static getRedisClientOptions () {
49 return Object.assign({}, 49 return Object.assign({},
50 (CONFIG.REDIS.AUTH && CONFIG.REDIS.AUTH != null) ? { password: CONFIG.REDIS.AUTH } : {}, 50 (CONFIG.REDIS.AUTH && CONFIG.REDIS.AUTH != null) ? { password: CONFIG.REDIS.AUTH } : {},
51 (CONFIG.REDIS.DB) ? { db: CONFIG.REDIS.DB } : {}, 51 (CONFIG.REDIS.DB) ? { db: CONFIG.REDIS.DB } : {},
@@ -55,6 +55,14 @@ class Redis {
55 ) 55 )
56 } 56 }
57 57
58 getClient () {
59 return this.client
60 }
61
62 getPrefix () {
63 return this.prefix
64 }
65
58 /************* Forgot password *************/ 66 /************* Forgot password *************/
59 67
60 async setResetPasswordVerificationString (userId: number) { 68 async setResetPasswordVerificationString (userId: number) {
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts
index 091c82d92..ef8611875 100644
--- a/server/middlewares/cache.ts
+++ b/server/middlewares/cache.ts
@@ -1,73 +1,16 @@
1import * as express from 'express'
2import * as AsyncLock from 'async-lock'
3import { parseDurationToMs } from '../helpers/core-utils'
4import { Redis } from '../lib/redis' 1import { Redis } from '../lib/redis'
5import { logger } from '../helpers/logger' 2import * as apicache from 'apicache'
6 3
7const lock = new AsyncLock({ timeout: 5000 }) 4// Ensure Redis is initialized
5Redis.Instance.init()
8 6
9function cacheRoute (lifetimeArg: string | number) { 7const options = {
10 const lifetime = parseDurationToMs(lifetimeArg) 8 redisClient: Redis.Instance.getClient(),
11 9 appendKey: () => Redis.Instance.getPrefix()
12 return async function (req: express.Request, res: express.Response, next: express.NextFunction) {
13 const redisKey = Redis.Instance.generateCachedRouteKey(req)
14
15 try {
16 await lock.acquire(redisKey, async (done) => {
17 const cached = await Redis.Instance.getCachedRoute(req)
18
19 // Not cached
20 if (!cached) {
21 logger.debug('No cached results for route %s.', req.originalUrl)
22
23 const sendSave = res.send.bind(res)
24 const redirectSave = res.redirect.bind(res)
25
26 res.send = (body) => {
27 if (res.statusCode >= 200 && res.statusCode < 400) {
28 const contentType = res.get('content-type')
29
30 Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode)
31 .then(() => done())
32 .catch(err => {
33 logger.error('Cannot cache route.', { err })
34 return done(err)
35 })
36 } else {
37 done()
38 }
39
40 return sendSave(body)
41 }
42
43 res.redirect = url => {
44 done()
45
46 return redirectSave(url)
47 }
48
49 return next()
50 }
51
52 if (cached.contentType) res.set('content-type', cached.contentType)
53
54 if (cached.statusCode) {
55 const statusCode = parseInt(cached.statusCode, 10)
56 if (!isNaN(statusCode)) res.status(statusCode)
57 }
58
59 logger.debug('Use cached result for %s.', req.originalUrl)
60 res.send(cached.body).end()
61
62 return done()
63 })
64 } catch (err) {
65 logger.error('Cannot serve cached route.', { err })
66 return next()
67 }
68 }
69} 10}
70 11
12const cacheRoute = apicache.options(options).middleware
13
71// --------------------------------------------------------------------------- 14// ---------------------------------------------------------------------------
72 15
73export { 16export {