Cache AP video route for 5 seconds

This commit is contained in:
Chocobozzz 2018-05-11 09:44:04 +02:00
parent 8a2db2e8cb
commit fd4484f19e
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
5 changed files with 42 additions and 30 deletions

View File

@ -3,7 +3,7 @@ import * as express from 'express'
import { VideoPrivacy } from '../../../shared/models/videos'
import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
import { pageToStartAndCount } from '../../helpers/core-utils'
import { ACTIVITY_PUB, CONFIG } from '../../initializers'
import { ACTIVITY_PUB, CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers'
import { buildVideoAnnounce } from '../../lib/activitypub/send'
import { audiencify, getAudience } from '../../lib/activitypub/send/misc'
import { createActivityData } from '../../lib/activitypub/send/send-create'
@ -17,6 +17,7 @@ import { VideoModel } from '../../models/video/video'
import { VideoChannelModel } from '../../models/video/video-channel'
import { VideoCommentModel } from '../../models/video/video-comment'
import { VideoShareModel } from '../../models/video/video-share'
import { cacheRoute } from '../../middlewares/cache'
const activityPubClientRouter = express.Router()
@ -34,6 +35,7 @@ activityPubClientRouter.get('/accounts?/:name/following',
)
activityPubClientRouter.get('/videos/watch/:id',
executeIfActivityPub(asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS))),
executeIfActivityPub(asyncMiddleware(videosGetValidator)),
executeIfActivityPub(asyncMiddleware(videoController))
)

View File

@ -1,5 +1,5 @@
import * as express from 'express'
import { CONFIG, FEEDS } from '../initializers/constants'
import { CONFIG, FEEDS, ROUTE_CACHE_LIFETIME } from '../initializers/constants'
import { asyncMiddleware, feedsValidator, setDefaultSort, videosSortValidator } from '../middlewares'
import { VideoModel } from '../models/video/video'
import * as Feed from 'pfeed'
@ -12,8 +12,8 @@ const feedsRouter = express.Router()
feedsRouter.get('/feeds/videos.:format',
videosSortValidator,
setDefaultSort,
asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)),
asyncMiddleware(feedsValidator),
asyncMiddleware(cacheRoute),
asyncMiddleware(generateFeed)
)

View File

@ -42,6 +42,13 @@ const OAUTH_LIFETIME = {
REFRESH_TOKEN: 1209600 // 2 weeks
}
const ROUTE_CACHE_LIFETIME = {
FEEDS: 1000 * 60 * 15, // 15 minutes
ACTIVITY_PUB: {
VIDEOS: 1000 * 5 // 5 seconds
}
}
// ---------------------------------------------------------------------------
// Number of points we add/remove after a successful/bad request
@ -413,8 +420,7 @@ const OPENGRAPH_AND_OEMBED_COMMENT = '<!-- open graph and oembed tags -->'
// ---------------------------------------------------------------------------
const FEEDS = {
COUNT: 20,
CACHE_LIFETIME: 1000 * 60 * 15 // 15 minutes
COUNT: 20
}
// ---------------------------------------------------------------------------
@ -458,6 +464,7 @@ export {
FOLLOW_STATES,
SERVER_ACTOR_NAME,
PRIVATE_RSA_KEY_SIZE,
ROUTE_CACHE_LIFETIME,
SORTABLE_COLUMNS,
FEEDS,
NSFW_POLICY_TYPES,

View File

@ -2,7 +2,7 @@ import * as express from 'express'
import { createClient, RedisClient } from 'redis'
import { logger } from '../helpers/logger'
import { generateRandomString } from '../helpers/utils'
import { CONFIG, FEEDS, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers'
import { CONFIG, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers'
type CachedRoute = {
body: string,
@ -67,14 +67,14 @@ class Redis {
return cached as CachedRoute
}
setCachedRoute (req: express.Request, body: any, contentType?: string, statusCode?: number) {
setCachedRoute (req: express.Request, body: any, lifetime: number, contentType?: string, statusCode?: number) {
const cached: CachedRoute = {
body: body.toString(),
contentType,
statusCode: statusCode.toString()
}
return this.setObject(this.buildCachedRouteKey(req), cached, FEEDS.CACHE_LIFETIME)
return this.setObject(this.buildCachedRouteKey(req), cached, lifetime)
}
listJobs (jobsPrefix: string, state: string, mode: 'alpha', order: 'ASC' | 'DESC', offset: number, count: number) {

View File

@ -2,36 +2,39 @@ import * as express from 'express'
import { Redis } from '../lib/redis'
import { logger } from '../helpers/logger'
async function cacheRoute (req: express.Request, res: express.Response, next: express.NextFunction) {
const cached = await Redis.Instance.getCachedRoute(req)
function cacheRoute (lifetime: number) {
return async function (req: express.Request, res: express.Response, next: express.NextFunction) {
const cached = await Redis.Instance.getCachedRoute(req)
// Not cached
if (!cached) {
logger.debug('Not cached result for route %s.', req.originalUrl)
// Not cached
if (!cached) {
logger.debug('Not cached result for route %s.', req.originalUrl)
const sendSave = res.send.bind(res)
const sendSave = res.send.bind(res)
res.send = (body) => {
if (res.statusCode >= 200 && res.statusCode < 400) {
Redis.Instance.setCachedRoute(req, body, res.getHeader('content-type').toString(), res.statusCode)
.catch(err => logger.error('Cannot cache route.', { err }))
res.send = (body) => {
if (res.statusCode >= 200 && res.statusCode < 400) {
const contentType = res.getHeader('content-type').toString()
Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode)
.catch(err => logger.error('Cannot cache route.', { err }))
}
return sendSave(body)
}
return sendSave(body)
return next()
}
return next()
if (cached.contentType) res.contentType(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)
return res.send(cached.body).end()
}
if (cached.contentType) res.contentType(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)
return res.send(cached.body).end()
}
// ---------------------------------------------------------------------------