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"
|
"@types/bluebird": "3.5.21"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"apicache": "^1.4.0",
|
||||||
"application-config": "^1.0.1",
|
"application-config": "^1.0.1",
|
||||||
"async": "^2.0.0",
|
"async": "^2.0.0",
|
||||||
"async-lock": "^1.1.2",
|
|
||||||
"async-lru": "^1.1.1",
|
"async-lru": "^1.1.1",
|
||||||
"bcrypt": "3.0.5",
|
"bcrypt": "3.0.5",
|
||||||
"bittorrent-tracker": "^9.0.0",
|
"bittorrent-tracker": "^9.0.0",
|
||||||
|
@ -159,6 +159,7 @@
|
||||||
"youtube-dl": "^1.12.2"
|
"youtube-dl": "^1.12.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/apicache": "^1.2.0",
|
||||||
"@types/async": "^2.0.40",
|
"@types/async": "^2.0.40",
|
||||||
"@types/async-lock": "^1.1.0",
|
"@types/async-lock": "^1.1.0",
|
||||||
"@types/bcrypt": "^3.0.0",
|
"@types/bcrypt": "^3.0.0",
|
||||||
|
|
|
@ -71,7 +71,7 @@ class JobQueue {
|
||||||
this.jobRedisPrefix = 'bull-' + WEBSERVER.HOST
|
this.jobRedisPrefix = 'bull-' + WEBSERVER.HOST
|
||||||
const queueOptions = {
|
const queueOptions = {
|
||||||
prefix: this.jobRedisPrefix,
|
prefix: this.jobRedisPrefix,
|
||||||
redis: Redis.getRedisClient(),
|
redis: Redis.getRedisClientOptions(),
|
||||||
settings: {
|
settings: {
|
||||||
maxStalledCount: 10 // transcoding could be long, so jobs can often be interrupted by restarts
|
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
|
if (this.initialized === true) return
|
||||||
this.initialized = true
|
this.initialized = true
|
||||||
|
|
||||||
this.client = createClient(Redis.getRedisClient())
|
this.client = createClient(Redis.getRedisClientOptions())
|
||||||
|
|
||||||
this.client.on('error', err => {
|
this.client.on('error', err => {
|
||||||
logger.error('Error in Redis client.', { err })
|
logger.error('Error in Redis client.', { err })
|
||||||
|
@ -45,7 +45,7 @@ class Redis {
|
||||||
this.prefix = 'redis-' + WEBSERVER.HOST + '-'
|
this.prefix = 'redis-' + WEBSERVER.HOST + '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
static getRedisClient () {
|
static getRedisClientOptions () {
|
||||||
return Object.assign({},
|
return Object.assign({},
|
||||||
(CONFIG.REDIS.AUTH && CONFIG.REDIS.AUTH != null) ? { password: CONFIG.REDIS.AUTH } : {},
|
(CONFIG.REDIS.AUTH && CONFIG.REDIS.AUTH != null) ? { password: CONFIG.REDIS.AUTH } : {},
|
||||||
(CONFIG.REDIS.DB) ? { db: CONFIG.REDIS.DB } : {},
|
(CONFIG.REDIS.DB) ? { db: CONFIG.REDIS.DB } : {},
|
||||||
|
@ -55,6 +55,14 @@ class Redis {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getClient () {
|
||||||
|
return this.client
|
||||||
|
}
|
||||||
|
|
||||||
|
getPrefix () {
|
||||||
|
return this.prefix
|
||||||
|
}
|
||||||
|
|
||||||
/************* Forgot password *************/
|
/************* Forgot password *************/
|
||||||
|
|
||||||
async setResetPasswordVerificationString (userId: number) {
|
async setResetPasswordVerificationString (userId: number) {
|
||||||
|
|
|
@ -1,73 +1,16 @@
|
||||||
import * as express from 'express'
|
|
||||||
import * as AsyncLock from 'async-lock'
|
|
||||||
import { parseDurationToMs } from '../helpers/core-utils'
|
|
||||||
import { Redis } from '../lib/redis'
|
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 options = {
|
||||||
const lifetime = parseDurationToMs(lifetimeArg)
|
redisClient: Redis.Instance.getClient(),
|
||||||
|
appendKey: () => Redis.Instance.getPrefix()
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -16,6 +16,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
any-observable "^0.3.0"
|
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":
|
"@types/async-lock@^1.1.0":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.1.1.tgz#81f218213bebcc5f740efe9648272c774a2e4b4b"
|
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"
|
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
|
||||||
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
|
||||||
|
|
||||||
"@types/redis@^2.8.5":
|
"@types/redis@*", "@types/redis@^2.8.5":
|
||||||
version "2.8.12"
|
version "2.8.12"
|
||||||
resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.12.tgz#6405d7ece0d6cc037151b7141cef9ad3cd06f3ac"
|
resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.12.tgz#6405d7ece0d6cc037151b7141cef9ad3cd06f3ac"
|
||||||
integrity sha512-eT5cGYr08OnF6OlAHdc2hVOBAKBpfQQNQHsWEvUwRPFiXRd+vv+hOHSSIo4xB7M5vZOZdjMT2OUlXYqo3YlIGQ==
|
integrity sha512-eT5cGYr08OnF6OlAHdc2hVOBAKBpfQQNQHsWEvUwRPFiXRd+vv+hOHSSIo4xB7M5vZOZdjMT2OUlXYqo3YlIGQ==
|
||||||
|
@ -548,6 +555,11 @@ anymatch@^2.0.0:
|
||||||
micromatch "^3.1.4"
|
micromatch "^3.1.4"
|
||||||
normalize-path "^2.1.1"
|
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:
|
append-field@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56"
|
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"
|
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||||
integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
|
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:
|
async-lru@^1.1.1:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/async-lru/-/async-lru-1.1.2.tgz#abe831f3a52123c87d44273615e203b1ef04692e"
|
resolved "https://registry.yarnpkg.com/async-lru/-/async-lru-1.1.2.tgz#abe831f3a52123c87d44273615e203b1ef04692e"
|
||||||
|
|
Loading…
Reference in a new issue