diff options
author | Chocobozzz <me@florianbigard.com> | 2020-02-04 15:00:47 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2020-02-04 15:00:47 +0100 |
commit | 7eba5e1fa81c8e54cb8fe298a96e8070afa50921 (patch) | |
tree | a6bd4b13dc0d65addfa82fcf200f2d1853a0723a /server/models | |
parent | e436baf0b00b3ecf3731aeba02437ebe4906ac5f (diff) | |
download | PeerTube-7eba5e1fa81c8e54cb8fe298a96e8070afa50921.tar.gz PeerTube-7eba5e1fa81c8e54cb8fe298a96e8070afa50921.tar.zst PeerTube-7eba5e1fa81c8e54cb8fe298a96e8070afa50921.zip |
Add model cache for video
When fetching only immutable attributes
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/model-cache.ts | 39 | ||||
-rw-r--r-- | server/models/video/video.ts | 30 |
2 files changed, 66 insertions, 3 deletions
diff --git a/server/models/model-cache.ts b/server/models/model-cache.ts index bfa163b6b..8afe3834f 100644 --- a/server/models/model-cache.ts +++ b/server/models/model-cache.ts | |||
@@ -6,6 +6,10 @@ type ModelCacheType = | |||
6 | 'local-account-name' | 6 | 'local-account-name' |
7 | | 'local-actor-name' | 7 | | 'local-actor-name' |
8 | | 'local-actor-url' | 8 | | 'local-actor-url' |
9 | | 'video-immutable' | ||
10 | |||
11 | type DeleteKey = | ||
12 | 'video' | ||
9 | 13 | ||
10 | class ModelCache { | 14 | class ModelCache { |
11 | 15 | ||
@@ -14,7 +18,14 @@ class ModelCache { | |||
14 | private readonly localCache: { [id in ModelCacheType]: Map<string, any> } = { | 18 | private readonly localCache: { [id in ModelCacheType]: Map<string, any> } = { |
15 | 'local-account-name': new Map(), | 19 | 'local-account-name': new Map(), |
16 | 'local-actor-name': new Map(), | 20 | 'local-actor-name': new Map(), |
17 | 'local-actor-url': new Map() | 21 | 'local-actor-url': new Map(), |
22 | 'video-immutable': new Map() | ||
23 | } | ||
24 | |||
25 | private readonly deleteIds: { | ||
26 | [deleteKey in DeleteKey]: Map<number, { cacheType: ModelCacheType, key: string }[]> | ||
27 | } = { | ||
28 | video: new Map() | ||
18 | } | 29 | } |
19 | 30 | ||
20 | private constructor () { | 31 | private constructor () { |
@@ -29,8 +40,9 @@ class ModelCache { | |||
29 | key: string | 40 | key: string |
30 | fun: () => Bluebird<T> | 41 | fun: () => Bluebird<T> |
31 | whitelist?: () => boolean | 42 | whitelist?: () => boolean |
43 | deleteKey?: DeleteKey | ||
32 | }) { | 44 | }) { |
33 | const { cacheType, key, fun, whitelist } = options | 45 | const { cacheType, key, fun, whitelist, deleteKey } = options |
34 | 46 | ||
35 | if (whitelist && whitelist() !== true) return fun() | 47 | if (whitelist && whitelist() !== true) return fun() |
36 | 48 | ||
@@ -42,11 +54,34 @@ class ModelCache { | |||
42 | } | 54 | } |
43 | 55 | ||
44 | return fun().then(m => { | 56 | return fun().then(m => { |
57 | if (!m) return m | ||
58 | |||
45 | if (!whitelist || whitelist()) cache.set(key, m) | 59 | if (!whitelist || whitelist()) cache.set(key, m) |
46 | 60 | ||
61 | if (deleteKey) { | ||
62 | const map = this.deleteIds[deleteKey] | ||
63 | if (!map.has(m.id)) map.set(m.id, []) | ||
64 | |||
65 | const a = map.get(m.id) | ||
66 | a.push({ cacheType, key }) | ||
67 | } | ||
68 | |||
47 | return m | 69 | return m |
48 | }) | 70 | }) |
49 | } | 71 | } |
72 | |||
73 | invalidateCache (deleteKey: DeleteKey, modelId: number) { | ||
74 | const map = this.deleteIds[deleteKey] | ||
75 | |||
76 | if (!map.has(modelId)) return | ||
77 | |||
78 | for (const toDelete of map.get(modelId)) { | ||
79 | logger.debug('Removing %s -> %d of model cache %s -> %s.', deleteKey, modelId, toDelete.cacheType, toDelete.key) | ||
80 | this.localCache[toDelete.cacheType].delete(toDelete.key) | ||
81 | } | ||
82 | |||
83 | map.delete(modelId) | ||
84 | } | ||
50 | } | 85 | } |
51 | 86 | ||
52 | export { | 87 | export { |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 1ec8d717e..9e02d163f 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -120,7 +120,7 @@ import { | |||
120 | MVideoFormattableDetails, | 120 | MVideoFormattableDetails, |
121 | MVideoForUser, | 121 | MVideoForUser, |
122 | MVideoFullLight, | 122 | MVideoFullLight, |
123 | MVideoIdThumbnail, | 123 | MVideoIdThumbnail, MVideoImmutable, |
124 | MVideoThumbnail, | 124 | MVideoThumbnail, |
125 | MVideoThumbnailBlacklist, | 125 | MVideoThumbnailBlacklist, |
126 | MVideoWithAllFiles, | 126 | MVideoWithAllFiles, |
@@ -132,6 +132,7 @@ import { MThumbnail } from '../../typings/models/video/thumbnail' | |||
132 | import { VideoFile } from '@shared/models/videos/video-file.model' | 132 | import { VideoFile } from '@shared/models/videos/video-file.model' |
133 | import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 133 | import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths' |
134 | import validator from 'validator' | 134 | import validator from 'validator' |
135 | import { ModelCache } from '@server/models/model-cache' | ||
135 | 136 | ||
136 | export enum ScopeNames { | 137 | export enum ScopeNames { |
137 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', | 138 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', |
@@ -1074,6 +1075,11 @@ export class VideoModel extends Model<VideoModel> { | |||
1074 | return undefined | 1075 | return undefined |
1075 | } | 1076 | } |
1076 | 1077 | ||
1078 | @BeforeDestroy | ||
1079 | static invalidateCache (instance: VideoModel) { | ||
1080 | ModelCache.Instance.invalidateCache('video', instance.id) | ||
1081 | } | ||
1082 | |||
1077 | static listLocal (): Bluebird<MVideoWithAllFiles[]> { | 1083 | static listLocal (): Bluebird<MVideoWithAllFiles[]> { |
1078 | const query = { | 1084 | const query = { |
1079 | where: { | 1085 | where: { |
@@ -1468,6 +1474,28 @@ export class VideoModel extends Model<VideoModel> { | |||
1468 | ]).findOne(options) | 1474 | ]).findOne(options) |
1469 | } | 1475 | } |
1470 | 1476 | ||
1477 | static loadImmutableAttributes (id: number | string, t?: Transaction): Bluebird<MVideoImmutable> { | ||
1478 | const fun = () => { | ||
1479 | const where = buildWhereIdOrUUID(id) | ||
1480 | const options = { | ||
1481 | attributes: [ | ||
1482 | 'id', 'url', 'uuid' | ||
1483 | ], | ||
1484 | where, | ||
1485 | transaction: t | ||
1486 | } | ||
1487 | |||
1488 | return VideoModel.unscoped().findOne(options) | ||
1489 | } | ||
1490 | |||
1491 | return ModelCache.Instance.doCache({ | ||
1492 | cacheType: 'video-immutable', | ||
1493 | key: '' + id, | ||
1494 | deleteKey: 'video', | ||
1495 | fun | ||
1496 | }) | ||
1497 | } | ||
1498 | |||
1471 | static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> { | 1499 | static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> { |
1472 | const where = buildWhereIdOrUUID(id) | 1500 | const where = buildWhereIdOrUUID(id) |
1473 | const options = { | 1501 | const options = { |