"@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",
"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",
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
}
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 })
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 } : {},
)
}
+ getClient () {
+ return this.client
+ }
+
+ getPrefix () {
+ return this.prefix
+ }
+
/************* Forgot password *************/
async setResetPasswordVerificationString (userId: number) {
-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()
- }
-
- 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 options = {
+ redisClient: Redis.Instance.getClient(),
+ appendKey: () => Redis.Instance.getPrefix()
}
+const cacheRoute = apicache.options(options).middleware
+
// ---------------------------------------------------------------------------
export {
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"
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==
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"
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"