]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/model-cache.ts
Add model cache for video
[github/Chocobozzz/PeerTube.git] / server / models / model-cache.ts
1 import { Model } from 'sequelize-typescript'
2 import * as Bluebird from 'bluebird'
3 import { logger } from '@server/helpers/logger'
4
5 type ModelCacheType =
6 'local-account-name'
7 | 'local-actor-name'
8 | 'local-actor-url'
9 | 'video-immutable'
10
11 type DeleteKey =
12 'video'
13
14 class ModelCache {
15
16 private static instance: ModelCache
17
18 private readonly localCache: { [id in ModelCacheType]: Map<string, any> } = {
19 'local-account-name': new Map(),
20 'local-actor-name': 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()
29 }
30
31 private constructor () {
32 }
33
34 static get Instance () {
35 return this.instance || (this.instance = new this())
36 }
37
38 doCache<T extends Model> (options: {
39 cacheType: ModelCacheType
40 key: string
41 fun: () => Bluebird<T>
42 whitelist?: () => boolean
43 deleteKey?: DeleteKey
44 }) {
45 const { cacheType, key, fun, whitelist, deleteKey } = options
46
47 if (whitelist && whitelist() !== true) return fun()
48
49 const cache = this.localCache[cacheType]
50
51 if (cache.has(key)) {
52 logger.debug('Model cache hit for %s -> %s.', cacheType, key)
53 return Bluebird.resolve<T>(cache.get(key))
54 }
55
56 return fun().then(m => {
57 if (!m) return m
58
59 if (!whitelist || whitelist()) cache.set(key, m)
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
69 return m
70 })
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 }
85 }
86
87 export {
88 ModelCache
89 }