Use apicache instead of our broken implementation
This commit is contained in:
parent
d0dba1fce6
commit
47f6409bb8
5 changed files with 34 additions and 75 deletions
|
@ -91,9 +91,9 @@
|
|||
"@types/bluebird": "3.5.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"apicache": "^1.4.0",
|
||||
"application-config": "^1.0.1",
|
||||
"async": "^2.0.0",
|
||||
"async-lock": "^1.1.2",
|
||||
"async-lru": "^1.1.1",
|
||||
"bcrypt": "3.0.5",
|
||||
"bittorrent-tracker": "^9.0.0",
|
||||
|
@ -159,6 +159,7 @@
|
|||
"youtube-dl": "^1.12.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/apicache": "^1.2.0",
|
||||
"@types/async": "^2.0.40",
|
||||
"@types/async-lock": "^1.1.0",
|
||||
"@types/bcrypt": "^3.0.0",
|
||||
|
|
|
@ -71,7 +71,7 @@ class JobQueue {
|
|||
this.jobRedisPrefix = 'bull-' + WEBSERVER.HOST
|
||||
const queueOptions = {
|
||||
prefix: this.jobRedisPrefix,
|
||||
redis: Redis.getRedisClient(),
|
||||
redis: Redis.getRedisClientOptions(),
|
||||
settings: {
|
||||
maxStalledCount: 10 // transcoding could be long, so jobs can often be interrupted by restarts
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class Redis {
|
|||
if (this.initialized === true) return
|
||||
this.initialized = true
|
||||
|
||||
this.client = createClient(Redis.getRedisClient())
|
||||
this.client = createClient(Redis.getRedisClientOptions())
|
||||
|
||||
this.client.on('error', err => {
|
||||
logger.error('Error in Redis client.', { err })
|
||||
|
@ -45,7 +45,7 @@ class Redis {
|
|||
this.prefix = 'redis-' + WEBSERVER.HOST + '-'
|
||||
}
|
||||
|
||||
static getRedisClient () {
|
||||
static getRedisClientOptions () {
|
||||
return Object.assign({},
|
||||
(CONFIG.REDIS.AUTH && CONFIG.REDIS.AUTH != null) ? { password: CONFIG.REDIS.AUTH } : {},
|
||||
(CONFIG.REDIS.DB) ? { db: CONFIG.REDIS.DB } : {},
|
||||
|
@ -55,6 +55,14 @@ class Redis {
|
|||
)
|
||||
}
|
||||
|
||||
getClient () {
|
||||
return this.client
|
||||
}
|
||||
|
||||
getPrefix () {
|
||||
return this.prefix
|
||||
}
|
||||
|
||||
/************* Forgot password *************/
|
||||
|
||||
async setResetPasswordVerificationString (userId: number) {
|
||||
|
|
|
@ -1,72 +1,15 @@
|
|||
import * as express from 'express'
|
||||
import * as AsyncLock from 'async-lock'
|
||||
import { parseDurationToMs } from '../helpers/core-utils'
|
||||
import { Redis } from '../lib/redis'
|
||||
import { logger } from '../helpers/logger'
|
||||
import * as apicache from 'apicache'
|
||||
|
||||
const lock = new AsyncLock({ timeout: 5000 })
|
||||
// Ensure Redis is initialized
|
||||
Redis.Instance.init()
|
||||
|
||||
function cacheRoute (lifetimeArg: string | number) {
|
||||
const lifetime = parseDurationToMs(lifetimeArg)
|
||||
|
||||
return async function (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const redisKey = Redis.Instance.generateCachedRouteKey(req)
|
||||
|
||||
try {
|
||||
await lock.acquire(redisKey, async (done) => {
|
||||
const cached = await Redis.Instance.getCachedRoute(req)
|
||||
|
||||
// Not cached
|
||||
if (!cached) {
|
||||
logger.debug('No cached results for route %s.', req.originalUrl)
|
||||
|
||||
const sendSave = res.send.bind(res)
|
||||
const redirectSave = res.redirect.bind(res)
|
||||
|
||||
res.send = (body) => {
|
||||
if (res.statusCode >= 200 && res.statusCode < 400) {
|
||||
const contentType = res.get('content-type')
|
||||
|
||||
Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode)
|
||||
.then(() => done())
|
||||
.catch(err => {
|
||||
logger.error('Cannot cache route.', { err })
|
||||
return done(err)
|
||||
})
|
||||
} else {
|
||||
done()
|
||||
const options = {
|
||||
redisClient: Redis.Instance.getClient(),
|
||||
appendKey: () => Redis.Instance.getPrefix()
|
||||
}
|
||||
|
||||
return sendSave(body)
|
||||
}
|
||||
|
||||
res.redirect = url => {
|
||||
done()
|
||||
|
||||
return redirectSave(url)
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
if (cached.contentType) res.set('content-type', cached.contentType)
|
||||
|
||||
if (cached.statusCode) {
|
||||
const statusCode = parseInt(cached.statusCode, 10)
|
||||
if (!isNaN(statusCode)) res.status(statusCode)
|
||||
}
|
||||
|
||||
logger.debug('Use cached result for %s.', req.originalUrl)
|
||||
res.send(cached.body).end()
|
||||
|
||||
return done()
|
||||
})
|
||||
} catch (err) {
|
||||
logger.error('Cannot serve cached route.', { err })
|
||||
return next()
|
||||
}
|
||||
}
|
||||
}
|
||||
const cacheRoute = apicache.options(options).middleware
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -16,6 +16,13 @@
|
|||
dependencies:
|
||||
any-observable "^0.3.0"
|
||||
|
||||
"@types/apicache@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/apicache/-/apicache-1.2.0.tgz#5f6e9225e66d22da97042a39ad626b3c158d650d"
|
||||
integrity sha512-8uatdizj2GbYHtS4u+x4k2aG1thG6JBWKRidcnauXav+Bxe3bHsWS8HSwcybuLE2q39/95cwb4hkHvqmP7ja2w==
|
||||
dependencies:
|
||||
"@types/redis" "*"
|
||||
|
||||
"@types/async-lock@^1.1.0":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.1.1.tgz#81f218213bebcc5f740efe9648272c774a2e4b4b"
|
||||
|
@ -276,7 +283,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||
|
||||
"@types/redis@^2.8.5":
|
||||
"@types/redis@*", "@types/redis@^2.8.5":
|
||||
version "2.8.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.12.tgz#6405d7ece0d6cc037151b7141cef9ad3cd06f3ac"
|
||||
integrity sha512-eT5cGYr08OnF6OlAHdc2hVOBAKBpfQQNQHsWEvUwRPFiXRd+vv+hOHSSIo4xB7M5vZOZdjMT2OUlXYqo3YlIGQ==
|
||||
|
@ -548,6 +555,11 @@ anymatch@^2.0.0:
|
|||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
apicache@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/apicache/-/apicache-1.4.0.tgz#3835fbe18717caca3a44cb6272d49b52cac30d3a"
|
||||
integrity sha512-pX/Sf9q9HNzAC5F+hPgxt8v3eQVZkXL/+8HpAnrDJXFmma80F2aHAAeWTql3BsG87lc3T6A7CFPNWMTl97L/7Q==
|
||||
|
||||
append-field@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56"
|
||||
|
@ -695,11 +707,6 @@ async-limiter@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
|
||||
|
||||
async-lock@^1.1.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.0.tgz#cd6a53cb1ec3f86af25eafdeb6bc7c6e317258b8"
|
||||
integrity sha512-81HzTQm4+qMj6PwNlnR+y9g7pDdGGzd/YBUrQnHk+BhR28ja2qv497NkQQc1KcKEqh/RShm07di2b0cIWVFrNQ==
|
||||
|
||||
async-lru@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/async-lru/-/async-lru-1.1.2.tgz#abe831f3a52123c87d44273615e203b1ef04692e"
|
||||
|
|
Loading…
Reference in a new issue