diff options
author | Chocobozzz <me@florianbigard.com> | 2018-05-11 09:44:04 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-05-11 15:24:17 +0200 |
commit | fd4484f19eae8b0a0c30d5d30e98880c8708516a (patch) | |
tree | 9dcb357413c84797b79e301fb843b1695e20d902 /server | |
parent | 8a2db2e8cb67f7f802ecb35be7b9154695f1a6ec (diff) | |
download | PeerTube-fd4484f19eae8b0a0c30d5d30e98880c8708516a.tar.gz PeerTube-fd4484f19eae8b0a0c30d5d30e98880c8708516a.tar.zst PeerTube-fd4484f19eae8b0a0c30d5d30e98880c8708516a.zip |
Cache AP video route for 5 seconds
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/activitypub/client.ts | 4 | ||||
-rw-r--r-- | server/controllers/feeds.ts | 4 | ||||
-rw-r--r-- | server/initializers/constants.ts | 11 | ||||
-rw-r--r-- | server/lib/redis.ts | 6 | ||||
-rw-r--r-- | server/middlewares/cache.ts | 43 |
5 files changed, 40 insertions, 28 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index f5ac9c466..5199b3f81 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -3,7 +3,7 @@ import * as express from 'express' | |||
3 | import { VideoPrivacy } from '../../../shared/models/videos' | 3 | import { VideoPrivacy } from '../../../shared/models/videos' |
4 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' | 4 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' |
5 | import { pageToStartAndCount } from '../../helpers/core-utils' | 5 | import { pageToStartAndCount } from '../../helpers/core-utils' |
6 | import { ACTIVITY_PUB, CONFIG } from '../../initializers' | 6 | import { ACTIVITY_PUB, CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers' |
7 | import { buildVideoAnnounce } from '../../lib/activitypub/send' | 7 | import { buildVideoAnnounce } from '../../lib/activitypub/send' |
8 | import { audiencify, getAudience } from '../../lib/activitypub/send/misc' | 8 | import { audiencify, getAudience } from '../../lib/activitypub/send/misc' |
9 | import { createActivityData } from '../../lib/activitypub/send/send-create' | 9 | import { createActivityData } from '../../lib/activitypub/send/send-create' |
@@ -17,6 +17,7 @@ import { VideoModel } from '../../models/video/video' | |||
17 | import { VideoChannelModel } from '../../models/video/video-channel' | 17 | import { VideoChannelModel } from '../../models/video/video-channel' |
18 | import { VideoCommentModel } from '../../models/video/video-comment' | 18 | import { VideoCommentModel } from '../../models/video/video-comment' |
19 | import { VideoShareModel } from '../../models/video/video-share' | 19 | import { VideoShareModel } from '../../models/video/video-share' |
20 | import { cacheRoute } from '../../middlewares/cache' | ||
20 | 21 | ||
21 | const activityPubClientRouter = express.Router() | 22 | const activityPubClientRouter = express.Router() |
22 | 23 | ||
@@ -34,6 +35,7 @@ activityPubClientRouter.get('/accounts?/:name/following', | |||
34 | ) | 35 | ) |
35 | 36 | ||
36 | activityPubClientRouter.get('/videos/watch/:id', | 37 | activityPubClientRouter.get('/videos/watch/:id', |
38 | executeIfActivityPub(asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS))), | ||
37 | executeIfActivityPub(asyncMiddleware(videosGetValidator)), | 39 | executeIfActivityPub(asyncMiddleware(videosGetValidator)), |
38 | executeIfActivityPub(asyncMiddleware(videoController)) | 40 | executeIfActivityPub(asyncMiddleware(videoController)) |
39 | ) | 41 | ) |
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts index 08f179509..92cf85050 100644 --- a/server/controllers/feeds.ts +++ b/server/controllers/feeds.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { CONFIG, FEEDS } from '../initializers/constants' | 2 | import { CONFIG, FEEDS, ROUTE_CACHE_LIFETIME } from '../initializers/constants' |
3 | import { asyncMiddleware, feedsValidator, setDefaultSort, videosSortValidator } from '../middlewares' | 3 | import { asyncMiddleware, feedsValidator, setDefaultSort, videosSortValidator } from '../middlewares' |
4 | import { VideoModel } from '../models/video/video' | 4 | import { VideoModel } from '../models/video/video' |
5 | import * as Feed from 'pfeed' | 5 | import * as Feed from 'pfeed' |
@@ -12,8 +12,8 @@ const feedsRouter = express.Router() | |||
12 | feedsRouter.get('/feeds/videos.:format', | 12 | feedsRouter.get('/feeds/videos.:format', |
13 | videosSortValidator, | 13 | videosSortValidator, |
14 | setDefaultSort, | 14 | setDefaultSort, |
15 | asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.FEEDS)), | ||
15 | asyncMiddleware(feedsValidator), | 16 | asyncMiddleware(feedsValidator), |
16 | asyncMiddleware(cacheRoute), | ||
17 | asyncMiddleware(generateFeed) | 17 | asyncMiddleware(generateFeed) |
18 | ) | 18 | ) |
19 | 19 | ||
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index c4e8522c2..cfa0203d2 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -42,6 +42,13 @@ const OAUTH_LIFETIME = { | |||
42 | REFRESH_TOKEN: 1209600 // 2 weeks | 42 | REFRESH_TOKEN: 1209600 // 2 weeks |
43 | } | 43 | } |
44 | 44 | ||
45 | const ROUTE_CACHE_LIFETIME = { | ||
46 | FEEDS: 1000 * 60 * 15, // 15 minutes | ||
47 | ACTIVITY_PUB: { | ||
48 | VIDEOS: 1000 * 5 // 5 seconds | ||
49 | } | ||
50 | } | ||
51 | |||
45 | // --------------------------------------------------------------------------- | 52 | // --------------------------------------------------------------------------- |
46 | 53 | ||
47 | // Number of points we add/remove after a successful/bad request | 54 | // 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 -->' | |||
413 | // --------------------------------------------------------------------------- | 420 | // --------------------------------------------------------------------------- |
414 | 421 | ||
415 | const FEEDS = { | 422 | const FEEDS = { |
416 | COUNT: 20, | 423 | COUNT: 20 |
417 | CACHE_LIFETIME: 1000 * 60 * 15 // 15 minutes | ||
418 | } | 424 | } |
419 | 425 | ||
420 | // --------------------------------------------------------------------------- | 426 | // --------------------------------------------------------------------------- |
@@ -458,6 +464,7 @@ export { | |||
458 | FOLLOW_STATES, | 464 | FOLLOW_STATES, |
459 | SERVER_ACTOR_NAME, | 465 | SERVER_ACTOR_NAME, |
460 | PRIVATE_RSA_KEY_SIZE, | 466 | PRIVATE_RSA_KEY_SIZE, |
467 | ROUTE_CACHE_LIFETIME, | ||
461 | SORTABLE_COLUMNS, | 468 | SORTABLE_COLUMNS, |
462 | FEEDS, | 469 | FEEDS, |
463 | NSFW_POLICY_TYPES, | 470 | NSFW_POLICY_TYPES, |
diff --git a/server/lib/redis.ts b/server/lib/redis.ts index 1e7c0a821..0acb9ff0e 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts | |||
@@ -2,7 +2,7 @@ import * as express from 'express' | |||
2 | import { createClient, RedisClient } from 'redis' | 2 | import { createClient, RedisClient } from 'redis' |
3 | import { logger } from '../helpers/logger' | 3 | import { logger } from '../helpers/logger' |
4 | import { generateRandomString } from '../helpers/utils' | 4 | import { generateRandomString } from '../helpers/utils' |
5 | import { CONFIG, FEEDS, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers' | 5 | import { CONFIG, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers' |
6 | 6 | ||
7 | type CachedRoute = { | 7 | type CachedRoute = { |
8 | body: string, | 8 | body: string, |
@@ -67,14 +67,14 @@ class Redis { | |||
67 | return cached as CachedRoute | 67 | return cached as CachedRoute |
68 | } | 68 | } |
69 | 69 | ||
70 | setCachedRoute (req: express.Request, body: any, contentType?: string, statusCode?: number) { | 70 | setCachedRoute (req: express.Request, body: any, lifetime: number, contentType?: string, statusCode?: number) { |
71 | const cached: CachedRoute = { | 71 | const cached: CachedRoute = { |
72 | body: body.toString(), | 72 | body: body.toString(), |
73 | contentType, | 73 | contentType, |
74 | statusCode: statusCode.toString() | 74 | statusCode: statusCode.toString() |
75 | } | 75 | } |
76 | 76 | ||
77 | return this.setObject(this.buildCachedRouteKey(req), cached, FEEDS.CACHE_LIFETIME) | 77 | return this.setObject(this.buildCachedRouteKey(req), cached, lifetime) |
78 | } | 78 | } |
79 | 79 | ||
80 | listJobs (jobsPrefix: string, state: string, mode: 'alpha', order: 'ASC' | 'DESC', offset: number, count: number) { | 80 | listJobs (jobsPrefix: string, state: string, mode: 'alpha', order: 'ASC' | 'DESC', offset: number, count: number) { |
diff --git a/server/middlewares/cache.ts b/server/middlewares/cache.ts index a2c7f7cbd..c589ef683 100644 --- a/server/middlewares/cache.ts +++ b/server/middlewares/cache.ts | |||
@@ -2,36 +2,39 @@ import * as express from 'express' | |||
2 | import { Redis } from '../lib/redis' | 2 | import { Redis } from '../lib/redis' |
3 | import { logger } from '../helpers/logger' | 3 | import { logger } from '../helpers/logger' |
4 | 4 | ||
5 | async function cacheRoute (req: express.Request, res: express.Response, next: express.NextFunction) { | 5 | function cacheRoute (lifetime: number) { |
6 | const cached = await Redis.Instance.getCachedRoute(req) | 6 | return async function (req: express.Request, res: express.Response, next: express.NextFunction) { |
7 | const cached = await Redis.Instance.getCachedRoute(req) | ||
7 | 8 | ||
8 | // Not cached | 9 | // Not cached |
9 | if (!cached) { | 10 | if (!cached) { |
10 | logger.debug('Not cached result for route %s.', req.originalUrl) | 11 | logger.debug('Not cached result for route %s.', req.originalUrl) |
11 | 12 | ||
12 | const sendSave = res.send.bind(res) | 13 | const sendSave = res.send.bind(res) |
13 | 14 | ||
14 | res.send = (body) => { | 15 | res.send = (body) => { |
15 | if (res.statusCode >= 200 && res.statusCode < 400) { | 16 | if (res.statusCode >= 200 && res.statusCode < 400) { |
16 | Redis.Instance.setCachedRoute(req, body, res.getHeader('content-type').toString(), res.statusCode) | 17 | const contentType = res.getHeader('content-type').toString() |
17 | .catch(err => logger.error('Cannot cache route.', { err })) | 18 | Redis.Instance.setCachedRoute(req, body, lifetime, contentType, res.statusCode) |
19 | .catch(err => logger.error('Cannot cache route.', { err })) | ||
20 | } | ||
21 | |||
22 | return sendSave(body) | ||
18 | } | 23 | } |
19 | 24 | ||
20 | return sendSave(body) | 25 | return next() |
21 | } | 26 | } |
22 | 27 | ||
23 | return next() | 28 | if (cached.contentType) res.contentType(cached.contentType) |
24 | } | ||
25 | 29 | ||
26 | if (cached.contentType) res.contentType(cached.contentType) | 30 | if (cached.statusCode) { |
31 | const statusCode = parseInt(cached.statusCode, 10) | ||
32 | if (!isNaN(statusCode)) res.status(statusCode) | ||
33 | } | ||
27 | 34 | ||
28 | if (cached.statusCode) { | 35 | logger.debug('Use cached result for %s.', req.originalUrl) |
29 | const statusCode = parseInt(cached.statusCode, 10) | 36 | return res.send(cached.body).end() |
30 | if (!isNaN(statusCode)) res.status(statusCode) | ||
31 | } | 37 | } |
32 | |||
33 | logger.debug('Use cached result for %s.', req.originalUrl) | ||
34 | return res.send(cached.body).end() | ||
35 | } | 38 | } |
36 | 39 | ||
37 | // --------------------------------------------------------------------------- | 40 | // --------------------------------------------------------------------------- |