From d74d29ad9e35929491cf37223398d2535ab23de0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 19 Mar 2019 14:23:17 +0100 Subject: Limit user tokens cache --- server/controllers/static.ts | 3 +- server/initializers/constants.ts | 13 ++++-- server/initializers/installer.ts | 10 ++-- .../lib/cache/abstract-video-static-file-cache.ts | 52 --------------------- server/lib/cache/actor-follow-score-cache.ts | 46 ------------------- server/lib/cache/index.ts | 3 -- server/lib/cache/videos-caption-cache.ts | 53 ---------------------- server/lib/cache/videos-preview-cache.ts | 42 ----------------- .../abstract-video-static-file-cache.ts | 52 +++++++++++++++++++++ server/lib/files-cache/actor-follow-score-cache.ts | 46 +++++++++++++++++++ server/lib/files-cache/index.ts | 3 ++ server/lib/files-cache/videos-caption-cache.ts | 53 ++++++++++++++++++++++ server/lib/files-cache/videos-preview-cache.ts | 42 +++++++++++++++++ .../handlers/activitypub-http-broadcast.ts | 3 +- .../job-queue/handlers/activitypub-http-unicast.ts | 2 +- server/lib/oauth-model.ts | 12 +++-- server/lib/schedulers/actor-follow-scheduler.ts | 2 +- 17 files changed, 224 insertions(+), 213 deletions(-) delete mode 100644 server/lib/cache/abstract-video-static-file-cache.ts delete mode 100644 server/lib/cache/actor-follow-score-cache.ts delete mode 100644 server/lib/cache/index.ts delete mode 100644 server/lib/cache/videos-caption-cache.ts delete mode 100644 server/lib/cache/videos-preview-cache.ts create mode 100644 server/lib/files-cache/abstract-video-static-file-cache.ts create mode 100644 server/lib/files-cache/actor-follow-score-cache.ts create mode 100644 server/lib/files-cache/index.ts create mode 100644 server/lib/files-cache/videos-caption-cache.ts create mode 100644 server/lib/files-cache/videos-preview-cache.ts (limited to 'server') diff --git a/server/controllers/static.ts b/server/controllers/static.ts index 7b14320e4..e65c7afd3 100644 --- a/server/controllers/static.ts +++ b/server/controllers/static.ts @@ -8,11 +8,10 @@ import { STATIC_MAX_AGE, STATIC_PATHS } from '../initializers' -import { VideosPreviewCache } from '../lib/cache' +import { VideosCaptionCache, VideosPreviewCache } from '../lib/files-cache' import { cacheRoute } from '../middlewares/cache' import { asyncMiddleware, videosGetValidator } from '../middlewares' import { VideoModel } from '../models/video/video' -import { VideosCaptionCache } from '../lib/cache/videos-caption-cache' import { UserModel } from '../models/account/user' import { VideoCommentModel } from '../models/video/video-comment' import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo' diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 7fac8a4d6..7a3ec3874 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -660,7 +660,7 @@ const EMBED_SIZE = { } // Sub folders of cache directory -const CACHE = { +const FILES_CACHE = { PREVIEWS: { DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'), MAX_AGE: 1000 * 3600 * 3 // 3 hours @@ -671,6 +671,12 @@ const CACHE = { } } +const CACHE = { + USER_TOKENS: { + MAX_SIZE: 10000 + } +} + const HLS_STREAMING_PLAYLIST_DIRECTORY = join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls') const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls') @@ -741,7 +747,7 @@ if (isTestInstance() === true) { JOB_ATTEMPTS['email'] = 1 - CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 + FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' @@ -759,7 +765,7 @@ export { ACCEPT_HEADERS, BCRYPT_SALT_SIZE, TRACKER_RATE_LIMITS, - CACHE, + FILES_CACHE, CONFIG, CONSTRAINTS_FIELDS, EMBED_SIZE, @@ -799,6 +805,7 @@ export { VIDEO_TRANSCODING_FPS, FFMPEG_NICE, VIDEO_ABUSE_STATES, + CACHE, JOB_REQUEST_TIMEOUT, USER_PASSWORD_RESET_LIFETIME, MEMOIZE_TTL, diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index cd2c942fd..07af96b68 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts @@ -6,7 +6,7 @@ import { UserModel } from '../models/account/user' import { ApplicationModel } from '../models/application/application' import { OAuthClientModel } from '../models/oauth/oauth-client' import { applicationExist, clientsExist, usersExist } from './checker-after-init' -import { CACHE, CONFIG, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants' +import { FILES_CACHE, CONFIG, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION } from './constants' import { sequelizeTypescript } from './database' import { remove, ensureDir } from 'fs-extra' @@ -42,8 +42,8 @@ export { // --------------------------------------------------------------------------- function removeCacheAndTmpDirectories () { - const cacheDirectories = Object.keys(CACHE) - .map(k => CACHE[k].DIRECTORY) + const cacheDirectories = Object.keys(FILES_CACHE) + .map(k => FILES_CACHE[k].DIRECTORY) const tasks: Promise[] = [] @@ -60,8 +60,8 @@ function removeCacheAndTmpDirectories () { function createDirectoriesIfNotExist () { const storage = CONFIG.STORAGE - const cacheDirectories = Object.keys(CACHE) - .map(k => CACHE[k].DIRECTORY) + const cacheDirectories = Object.keys(FILES_CACHE) + .map(k => FILES_CACHE[k].DIRECTORY) const tasks: Promise[] = [] for (const key of Object.keys(storage)) { diff --git a/server/lib/cache/abstract-video-static-file-cache.ts b/server/lib/cache/abstract-video-static-file-cache.ts deleted file mode 100644 index 7512f2b9d..000000000 --- a/server/lib/cache/abstract-video-static-file-cache.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as AsyncLRU from 'async-lru' -import { createWriteStream, remove } from 'fs-extra' -import { logger } from '../../helpers/logger' -import { VideoModel } from '../../models/video/video' -import { fetchRemoteVideoStaticFile } from '../activitypub' - -export abstract class AbstractVideoStaticFileCache { - - protected lru - - abstract getFilePath (params: T): Promise - - // Load and save the remote file, then return the local path from filesystem - protected abstract loadRemoteFile (key: string): Promise - - init (max: number, maxAge: number) { - this.lru = new AsyncLRU({ - max, - maxAge, - load: (key, cb) => { - this.loadRemoteFile(key) - .then(res => cb(null, res)) - .catch(err => cb(err)) - } - }) - - this.lru.on('evict', (obj: { key: string, value: string }) => { - remove(obj.value) - .then(() => logger.debug('%s evicted from %s', obj.value, this.constructor.name)) - }) - } - - protected loadFromLRU (key: string) { - return new Promise((res, rej) => { - this.lru.get(key, (err, value) => { - err ? rej(err) : res(value) - }) - }) - } - - protected saveRemoteVideoFileAndReturnPath (video: VideoModel, remoteStaticPath: string, destPath: string) { - return new Promise((res, rej) => { - const req = fetchRemoteVideoStaticFile(video, remoteStaticPath, rej) - - const stream = createWriteStream(destPath) - - req.pipe(stream) - .on('error', (err) => rej(err)) - .on('finish', () => res(destPath)) - }) - } -} diff --git a/server/lib/cache/actor-follow-score-cache.ts b/server/lib/cache/actor-follow-score-cache.ts deleted file mode 100644 index d070bde09..000000000 --- a/server/lib/cache/actor-follow-score-cache.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ACTOR_FOLLOW_SCORE } from '../../initializers' -import { logger } from '../../helpers/logger' - -// Cache follows scores, instead of writing them too often in database -// Keep data in memory, we don't really need Redis here as we don't really care to loose some scores -class ActorFollowScoreCache { - - private static instance: ActorFollowScoreCache - private pendingFollowsScore: { [ url: string ]: number } = {} - - private constructor () {} - - static get Instance () { - return this.instance || (this.instance = new this()) - } - - updateActorFollowsScore (goodInboxes: string[], badInboxes: string[]) { - if (goodInboxes.length === 0 && badInboxes.length === 0) return - - logger.info('Updating %d good actor follows and %d bad actor follows scores in cache.', goodInboxes.length, badInboxes.length) - - for (const goodInbox of goodInboxes) { - if (this.pendingFollowsScore[goodInbox] === undefined) this.pendingFollowsScore[goodInbox] = 0 - - this.pendingFollowsScore[goodInbox] += ACTOR_FOLLOW_SCORE.BONUS - } - - for (const badInbox of badInboxes) { - if (this.pendingFollowsScore[badInbox] === undefined) this.pendingFollowsScore[badInbox] = 0 - - this.pendingFollowsScore[badInbox] += ACTOR_FOLLOW_SCORE.PENALTY - } - } - - getPendingFollowsScoreCopy () { - return this.pendingFollowsScore - } - - clearPendingFollowsScore () { - this.pendingFollowsScore = {} - } -} - -export { - ActorFollowScoreCache -} diff --git a/server/lib/cache/index.ts b/server/lib/cache/index.ts deleted file mode 100644 index e921d04a7..000000000 --- a/server/lib/cache/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './actor-follow-score-cache' -export * from './videos-preview-cache' -export * from './videos-caption-cache' diff --git a/server/lib/cache/videos-caption-cache.ts b/server/lib/cache/videos-caption-cache.ts deleted file mode 100644 index f240affbc..000000000 --- a/server/lib/cache/videos-caption-cache.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { join } from 'path' -import { CACHE, CONFIG } from '../../initializers' -import { VideoModel } from '../../models/video/video' -import { VideoCaptionModel } from '../../models/video/video-caption' -import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' - -type GetPathParam = { videoId: string, language: string } - -class VideosCaptionCache extends AbstractVideoStaticFileCache { - - private static readonly KEY_DELIMITER = '%' - private static instance: VideosCaptionCache - - private constructor () { - super() - } - - static get Instance () { - return this.instance || (this.instance = new this()) - } - - async getFilePath (params: GetPathParam) { - const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(params.videoId, params.language) - if (!videoCaption) return undefined - - if (videoCaption.isOwned()) return join(CONFIG.STORAGE.CAPTIONS_DIR, videoCaption.getCaptionName()) - - const key = params.videoId + VideosCaptionCache.KEY_DELIMITER + params.language - return this.loadFromLRU(key) - } - - protected async loadRemoteFile (key: string) { - const [ videoId, language ] = key.split(VideosCaptionCache.KEY_DELIMITER) - - const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(videoId, language) - if (!videoCaption) return undefined - - if (videoCaption.isOwned()) throw new Error('Cannot load remote caption of owned video.') - - // Used to fetch the path - const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) - if (!video) return undefined - - const remoteStaticPath = videoCaption.getCaptionStaticPath() - const destPath = join(CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName()) - - return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) - } -} - -export { - VideosCaptionCache -} diff --git a/server/lib/cache/videos-preview-cache.ts b/server/lib/cache/videos-preview-cache.ts deleted file mode 100644 index a5d6f5b62..000000000 --- a/server/lib/cache/videos-preview-cache.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { join } from 'path' -import { CACHE, CONFIG, STATIC_PATHS } from '../../initializers' -import { VideoModel } from '../../models/video/video' -import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' - -class VideosPreviewCache extends AbstractVideoStaticFileCache { - - private static instance: VideosPreviewCache - - private constructor () { - super() - } - - static get Instance () { - return this.instance || (this.instance = new this()) - } - - async getFilePath (videoUUID: string) { - const video = await VideoModel.loadByUUIDWithFile(videoUUID) - if (!video) return undefined - - if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName()) - - return this.loadFromLRU(videoUUID) - } - - protected async loadRemoteFile (key: string) { - const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(key) - if (!video) return undefined - - if (video.isOwned()) throw new Error('Cannot load remote preview of owned video.') - - const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreviewName()) - const destPath = join(CACHE.PREVIEWS.DIRECTORY, video.getPreviewName()) - - return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) - } -} - -export { - VideosPreviewCache -} diff --git a/server/lib/files-cache/abstract-video-static-file-cache.ts b/server/lib/files-cache/abstract-video-static-file-cache.ts new file mode 100644 index 000000000..7512f2b9d --- /dev/null +++ b/server/lib/files-cache/abstract-video-static-file-cache.ts @@ -0,0 +1,52 @@ +import * as AsyncLRU from 'async-lru' +import { createWriteStream, remove } from 'fs-extra' +import { logger } from '../../helpers/logger' +import { VideoModel } from '../../models/video/video' +import { fetchRemoteVideoStaticFile } from '../activitypub' + +export abstract class AbstractVideoStaticFileCache { + + protected lru + + abstract getFilePath (params: T): Promise + + // Load and save the remote file, then return the local path from filesystem + protected abstract loadRemoteFile (key: string): Promise + + init (max: number, maxAge: number) { + this.lru = new AsyncLRU({ + max, + maxAge, + load: (key, cb) => { + this.loadRemoteFile(key) + .then(res => cb(null, res)) + .catch(err => cb(err)) + } + }) + + this.lru.on('evict', (obj: { key: string, value: string }) => { + remove(obj.value) + .then(() => logger.debug('%s evicted from %s', obj.value, this.constructor.name)) + }) + } + + protected loadFromLRU (key: string) { + return new Promise((res, rej) => { + this.lru.get(key, (err, value) => { + err ? rej(err) : res(value) + }) + }) + } + + protected saveRemoteVideoFileAndReturnPath (video: VideoModel, remoteStaticPath: string, destPath: string) { + return new Promise((res, rej) => { + const req = fetchRemoteVideoStaticFile(video, remoteStaticPath, rej) + + const stream = createWriteStream(destPath) + + req.pipe(stream) + .on('error', (err) => rej(err)) + .on('finish', () => res(destPath)) + }) + } +} diff --git a/server/lib/files-cache/actor-follow-score-cache.ts b/server/lib/files-cache/actor-follow-score-cache.ts new file mode 100644 index 000000000..d070bde09 --- /dev/null +++ b/server/lib/files-cache/actor-follow-score-cache.ts @@ -0,0 +1,46 @@ +import { ACTOR_FOLLOW_SCORE } from '../../initializers' +import { logger } from '../../helpers/logger' + +// Cache follows scores, instead of writing them too often in database +// Keep data in memory, we don't really need Redis here as we don't really care to loose some scores +class ActorFollowScoreCache { + + private static instance: ActorFollowScoreCache + private pendingFollowsScore: { [ url: string ]: number } = {} + + private constructor () {} + + static get Instance () { + return this.instance || (this.instance = new this()) + } + + updateActorFollowsScore (goodInboxes: string[], badInboxes: string[]) { + if (goodInboxes.length === 0 && badInboxes.length === 0) return + + logger.info('Updating %d good actor follows and %d bad actor follows scores in cache.', goodInboxes.length, badInboxes.length) + + for (const goodInbox of goodInboxes) { + if (this.pendingFollowsScore[goodInbox] === undefined) this.pendingFollowsScore[goodInbox] = 0 + + this.pendingFollowsScore[goodInbox] += ACTOR_FOLLOW_SCORE.BONUS + } + + for (const badInbox of badInboxes) { + if (this.pendingFollowsScore[badInbox] === undefined) this.pendingFollowsScore[badInbox] = 0 + + this.pendingFollowsScore[badInbox] += ACTOR_FOLLOW_SCORE.PENALTY + } + } + + getPendingFollowsScoreCopy () { + return this.pendingFollowsScore + } + + clearPendingFollowsScore () { + this.pendingFollowsScore = {} + } +} + +export { + ActorFollowScoreCache +} diff --git a/server/lib/files-cache/index.ts b/server/lib/files-cache/index.ts new file mode 100644 index 000000000..e921d04a7 --- /dev/null +++ b/server/lib/files-cache/index.ts @@ -0,0 +1,3 @@ +export * from './actor-follow-score-cache' +export * from './videos-preview-cache' +export * from './videos-caption-cache' diff --git a/server/lib/files-cache/videos-caption-cache.ts b/server/lib/files-cache/videos-caption-cache.ts new file mode 100644 index 000000000..fe5b441af --- /dev/null +++ b/server/lib/files-cache/videos-caption-cache.ts @@ -0,0 +1,53 @@ +import { join } from 'path' +import { FILES_CACHE, CONFIG } from '../../initializers' +import { VideoModel } from '../../models/video/video' +import { VideoCaptionModel } from '../../models/video/video-caption' +import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' + +type GetPathParam = { videoId: string, language: string } + +class VideosCaptionCache extends AbstractVideoStaticFileCache { + + private static readonly KEY_DELIMITER = '%' + private static instance: VideosCaptionCache + + private constructor () { + super() + } + + static get Instance () { + return this.instance || (this.instance = new this()) + } + + async getFilePath (params: GetPathParam) { + const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(params.videoId, params.language) + if (!videoCaption) return undefined + + if (videoCaption.isOwned()) return join(CONFIG.STORAGE.CAPTIONS_DIR, videoCaption.getCaptionName()) + + const key = params.videoId + VideosCaptionCache.KEY_DELIMITER + params.language + return this.loadFromLRU(key) + } + + protected async loadRemoteFile (key: string) { + const [ videoId, language ] = key.split(VideosCaptionCache.KEY_DELIMITER) + + const videoCaption = await VideoCaptionModel.loadByVideoIdAndLanguage(videoId, language) + if (!videoCaption) return undefined + + if (videoCaption.isOwned()) throw new Error('Cannot load remote caption of owned video.') + + // Used to fetch the path + const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) + if (!video) return undefined + + const remoteStaticPath = videoCaption.getCaptionStaticPath() + const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName()) + + return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) + } +} + +export { + VideosCaptionCache +} diff --git a/server/lib/files-cache/videos-preview-cache.ts b/server/lib/files-cache/videos-preview-cache.ts new file mode 100644 index 000000000..01cd3647e --- /dev/null +++ b/server/lib/files-cache/videos-preview-cache.ts @@ -0,0 +1,42 @@ +import { join } from 'path' +import { FILES_CACHE, CONFIG, STATIC_PATHS } from '../../initializers' +import { VideoModel } from '../../models/video/video' +import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' + +class VideosPreviewCache extends AbstractVideoStaticFileCache { + + private static instance: VideosPreviewCache + + private constructor () { + super() + } + + static get Instance () { + return this.instance || (this.instance = new this()) + } + + async getFilePath (videoUUID: string) { + const video = await VideoModel.loadByUUIDWithFile(videoUUID) + if (!video) return undefined + + if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName()) + + return this.loadFromLRU(videoUUID) + } + + protected async loadRemoteFile (key: string) { + const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(key) + if (!video) return undefined + + if (video.isOwned()) throw new Error('Cannot load remote preview of owned video.') + + const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreviewName()) + const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, video.getPreviewName()) + + return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) + } +} + +export { + VideosPreviewCache +} diff --git a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts index 9493945ff..2b1e21c39 100644 --- a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts +++ b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts @@ -2,10 +2,9 @@ import * as Bull from 'bull' import * as Bluebird from 'bluebird' import { logger } from '../../../helpers/logger' import { doRequest } from '../../../helpers/requests' -import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers' -import { ActorFollowScoreCache } from '../../cache' +import { ActorFollowScoreCache } from '../../files-cache' export type ActivitypubHttpBroadcastPayload = { uris: string[] diff --git a/server/lib/job-queue/handlers/activitypub-http-unicast.ts b/server/lib/job-queue/handlers/activitypub-http-unicast.ts index 3973dcdc8..59de7119a 100644 --- a/server/lib/job-queue/handlers/activitypub-http-unicast.ts +++ b/server/lib/job-queue/handlers/activitypub-http-unicast.ts @@ -3,7 +3,7 @@ import { logger } from '../../../helpers/logger' import { doRequest } from '../../../helpers/requests' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { JOB_REQUEST_TIMEOUT } from '../../../initializers' -import { ActorFollowScoreCache } from '../../cache' +import { ActorFollowScoreCache } from '../../files-cache' export type ActivitypubHttpUnicastPayload = { uri: string diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts index 2cd2ae97c..5b4a2bcf9 100644 --- a/server/lib/oauth-model.ts +++ b/server/lib/oauth-model.ts @@ -4,12 +4,12 @@ import { logger } from '../helpers/logger' import { UserModel } from '../models/account/user' import { OAuthClientModel } from '../models/oauth/oauth-client' import { OAuthTokenModel } from '../models/oauth/oauth-token' -import { CONFIG } from '../initializers/constants' +import { CONFIG, CACHE } from '../initializers/constants' import { Transaction } from 'sequelize' type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date } -const accessTokenCache: { [ accessToken: string ]: OAuthTokenModel } = {} -const userHavingToken: { [ userId: number ]: string } = {} +let accessTokenCache: { [ accessToken: string ]: OAuthTokenModel } = {} +let userHavingToken: { [ userId: number ]: string } = {} // --------------------------------------------------------------------------- @@ -43,6 +43,12 @@ function getAccessToken (bearerToken: string) { return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken) .then(tokenModel => { if (tokenModel) { + // Reinit our cache + if (Object.keys(accessTokenCache).length > CACHE.USER_TOKENS.MAX_SIZE) { + accessTokenCache = {} + userHavingToken = {} + } + accessTokenCache[ bearerToken ] = tokenModel userHavingToken[ tokenModel.userId ] = tokenModel.accessToken } diff --git a/server/lib/schedulers/actor-follow-scheduler.ts b/server/lib/schedulers/actor-follow-scheduler.ts index 3967be7f8..05e6bd139 100644 --- a/server/lib/schedulers/actor-follow-scheduler.ts +++ b/server/lib/schedulers/actor-follow-scheduler.ts @@ -3,7 +3,7 @@ import { logger } from '../../helpers/logger' import { ActorFollowModel } from '../../models/activitypub/actor-follow' import { AbstractScheduler } from './abstract-scheduler' import { SCHEDULER_INTERVALS_MS } from '../../initializers' -import { ActorFollowScoreCache } from '../cache' +import { ActorFollowScoreCache } from '../files-cache' export class ActorFollowScheduler extends AbstractScheduler { -- cgit v1.2.3