Limit user tokens cache

This commit is contained in:
Chocobozzz 2019-03-19 14:23:17 +01:00
parent 9f79ade627
commit d74d29ad9e
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
13 changed files with 36 additions and 25 deletions

View File

@ -28,7 +28,7 @@ import { checkMissedConfig, checkFFmpeg } from './server/initializers/checker-be
// Do not use barrels because we don't want to load all modules here (we need to initialize database first) // Do not use barrels because we don't want to load all modules here (we need to initialize database first)
import { logger } from './server/helpers/logger' import { logger } from './server/helpers/logger'
import { API_VERSION, CONFIG, CACHE } from './server/initializers/constants' import { API_VERSION, CONFIG, FILES_CACHE } from './server/initializers/constants'
const missed = checkMissedConfig() const missed = checkMissedConfig()
if (missed.length !== 0) { if (missed.length !== 0) {
@ -82,7 +82,7 @@ migrate()
import { installApplication } from './server/initializers' import { installApplication } from './server/initializers'
import { Emailer } from './server/lib/emailer' import { Emailer } from './server/lib/emailer'
import { JobQueue } from './server/lib/job-queue' import { JobQueue } from './server/lib/job-queue'
import { VideosPreviewCache, VideosCaptionCache } from './server/lib/cache' import { VideosPreviewCache, VideosCaptionCache } from './server/lib/files-cache'
import { import {
activityPubRouter, activityPubRouter,
apiRouter, apiRouter,
@ -218,8 +218,8 @@ async function startApplication () {
]) ])
// Caches initializations // Caches initializations
VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE) VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, FILES_CACHE.PREVIEWS.MAX_AGE)
VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, CACHE.VIDEO_CAPTIONS.MAX_AGE) VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE)
// Enable Schedulers // Enable Schedulers
ActorFollowScheduler.Instance.enable() ActorFollowScheduler.Instance.enable()

View File

@ -8,11 +8,10 @@ import {
STATIC_MAX_AGE, STATIC_MAX_AGE,
STATIC_PATHS STATIC_PATHS
} from '../initializers' } from '../initializers'
import { VideosPreviewCache } from '../lib/cache' import { VideosCaptionCache, VideosPreviewCache } from '../lib/files-cache'
import { cacheRoute } from '../middlewares/cache' import { cacheRoute } from '../middlewares/cache'
import { asyncMiddleware, videosGetValidator } from '../middlewares' import { asyncMiddleware, videosGetValidator } from '../middlewares'
import { VideoModel } from '../models/video/video' import { VideoModel } from '../models/video/video'
import { VideosCaptionCache } from '../lib/cache/videos-caption-cache'
import { UserModel } from '../models/account/user' import { UserModel } from '../models/account/user'
import { VideoCommentModel } from '../models/video/video-comment' import { VideoCommentModel } from '../models/video/video-comment'
import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo' import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo'

View File

@ -660,7 +660,7 @@ const EMBED_SIZE = {
} }
// Sub folders of cache directory // Sub folders of cache directory
const CACHE = { const FILES_CACHE = {
PREVIEWS: { PREVIEWS: {
DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'), DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'),
MAX_AGE: 1000 * 3600 * 3 // 3 hours 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_STREAMING_PLAYLIST_DIRECTORY = join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls')
const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls') const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls')
@ -741,7 +747,7 @@ if (isTestInstance() === true) {
JOB_ATTEMPTS['email'] = 1 JOB_ATTEMPTS['email'] = 1
CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 1
ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms'
@ -759,7 +765,7 @@ export {
ACCEPT_HEADERS, ACCEPT_HEADERS,
BCRYPT_SALT_SIZE, BCRYPT_SALT_SIZE,
TRACKER_RATE_LIMITS, TRACKER_RATE_LIMITS,
CACHE, FILES_CACHE,
CONFIG, CONFIG,
CONSTRAINTS_FIELDS, CONSTRAINTS_FIELDS,
EMBED_SIZE, EMBED_SIZE,
@ -799,6 +805,7 @@ export {
VIDEO_TRANSCODING_FPS, VIDEO_TRANSCODING_FPS,
FFMPEG_NICE, FFMPEG_NICE,
VIDEO_ABUSE_STATES, VIDEO_ABUSE_STATES,
CACHE,
JOB_REQUEST_TIMEOUT, JOB_REQUEST_TIMEOUT,
USER_PASSWORD_RESET_LIFETIME, USER_PASSWORD_RESET_LIFETIME,
MEMOIZE_TTL, MEMOIZE_TTL,

View File

@ -6,7 +6,7 @@ import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application' import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client' import { OAuthClientModel } from '../models/oauth/oauth-client'
import { applicationExist, clientsExist, usersExist } from './checker-after-init' 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 { sequelizeTypescript } from './database'
import { remove, ensureDir } from 'fs-extra' import { remove, ensureDir } from 'fs-extra'
@ -42,8 +42,8 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function removeCacheAndTmpDirectories () { function removeCacheAndTmpDirectories () {
const cacheDirectories = Object.keys(CACHE) const cacheDirectories = Object.keys(FILES_CACHE)
.map(k => CACHE[k].DIRECTORY) .map(k => FILES_CACHE[k].DIRECTORY)
const tasks: Promise<any>[] = [] const tasks: Promise<any>[] = []
@ -60,8 +60,8 @@ function removeCacheAndTmpDirectories () {
function createDirectoriesIfNotExist () { function createDirectoriesIfNotExist () {
const storage = CONFIG.STORAGE const storage = CONFIG.STORAGE
const cacheDirectories = Object.keys(CACHE) const cacheDirectories = Object.keys(FILES_CACHE)
.map(k => CACHE[k].DIRECTORY) .map(k => FILES_CACHE[k].DIRECTORY)
const tasks: Promise<void>[] = [] const tasks: Promise<void>[] = []
for (const key of Object.keys(storage)) { for (const key of Object.keys(storage)) {

View File

@ -1,5 +1,5 @@
import { join } from 'path' import { join } from 'path'
import { CACHE, CONFIG } from '../../initializers' import { FILES_CACHE, CONFIG } from '../../initializers'
import { VideoModel } from '../../models/video/video' import { VideoModel } from '../../models/video/video'
import { VideoCaptionModel } from '../../models/video/video-caption' import { VideoCaptionModel } from '../../models/video/video-caption'
import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache'
@ -42,7 +42,7 @@ class VideosCaptionCache extends AbstractVideoStaticFileCache <GetPathParam> {
if (!video) return undefined if (!video) return undefined
const remoteStaticPath = videoCaption.getCaptionStaticPath() const remoteStaticPath = videoCaption.getCaptionStaticPath()
const destPath = join(CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName()) const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.getCaptionName())
return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath)
} }

View File

@ -1,5 +1,5 @@
import { join } from 'path' import { join } from 'path'
import { CACHE, CONFIG, STATIC_PATHS } from '../../initializers' import { FILES_CACHE, CONFIG, STATIC_PATHS } from '../../initializers'
import { VideoModel } from '../../models/video/video' import { VideoModel } from '../../models/video/video'
import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache' import { AbstractVideoStaticFileCache } from './abstract-video-static-file-cache'
@ -31,7 +31,7 @@ class VideosPreviewCache extends AbstractVideoStaticFileCache <string> {
if (video.isOwned()) throw new Error('Cannot load remote preview of owned video.') if (video.isOwned()) throw new Error('Cannot load remote preview of owned video.')
const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreviewName()) const remoteStaticPath = join(STATIC_PATHS.PREVIEWS, video.getPreviewName())
const destPath = join(CACHE.PREVIEWS.DIRECTORY, video.getPreviewName()) const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, video.getPreviewName())
return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath) return this.saveRemoteVideoFileAndReturnPath(video, remoteStaticPath, destPath)
} }

View File

@ -2,10 +2,9 @@ import * as Bull from 'bull'
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers/logger'
import { doRequest } from '../../../helpers/requests' import { doRequest } from '../../../helpers/requests'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers' import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers'
import { ActorFollowScoreCache } from '../../cache' import { ActorFollowScoreCache } from '../../files-cache'
export type ActivitypubHttpBroadcastPayload = { export type ActivitypubHttpBroadcastPayload = {
uris: string[] uris: string[]

View File

@ -3,7 +3,7 @@ import { logger } from '../../../helpers/logger'
import { doRequest } from '../../../helpers/requests' import { doRequest } from '../../../helpers/requests'
import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
import { JOB_REQUEST_TIMEOUT } from '../../../initializers' import { JOB_REQUEST_TIMEOUT } from '../../../initializers'
import { ActorFollowScoreCache } from '../../cache' import { ActorFollowScoreCache } from '../../files-cache'
export type ActivitypubHttpUnicastPayload = { export type ActivitypubHttpUnicastPayload = {
uri: string uri: string

View File

@ -4,12 +4,12 @@ import { logger } from '../helpers/logger'
import { UserModel } from '../models/account/user' import { UserModel } from '../models/account/user'
import { OAuthClientModel } from '../models/oauth/oauth-client' import { OAuthClientModel } from '../models/oauth/oauth-client'
import { OAuthTokenModel } from '../models/oauth/oauth-token' import { OAuthTokenModel } from '../models/oauth/oauth-token'
import { CONFIG } from '../initializers/constants' import { CONFIG, CACHE } from '../initializers/constants'
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date } type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
const accessTokenCache: { [ accessToken: string ]: OAuthTokenModel } = {} let accessTokenCache: { [ accessToken: string ]: OAuthTokenModel } = {}
const userHavingToken: { [ userId: number ]: string } = {} let userHavingToken: { [ userId: number ]: string } = {}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -43,6 +43,12 @@ function getAccessToken (bearerToken: string) {
return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken) return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken)
.then(tokenModel => { .then(tokenModel => {
if (tokenModel) { if (tokenModel) {
// Reinit our cache
if (Object.keys(accessTokenCache).length > CACHE.USER_TOKENS.MAX_SIZE) {
accessTokenCache = {}
userHavingToken = {}
}
accessTokenCache[ bearerToken ] = tokenModel accessTokenCache[ bearerToken ] = tokenModel
userHavingToken[ tokenModel.userId ] = tokenModel.accessToken userHavingToken[ tokenModel.userId ] = tokenModel.accessToken
} }

View File

@ -3,7 +3,7 @@ import { logger } from '../../helpers/logger'
import { ActorFollowModel } from '../../models/activitypub/actor-follow' import { ActorFollowModel } from '../../models/activitypub/actor-follow'
import { AbstractScheduler } from './abstract-scheduler' import { AbstractScheduler } from './abstract-scheduler'
import { SCHEDULER_INTERVALS_MS } from '../../initializers' import { SCHEDULER_INTERVALS_MS } from '../../initializers'
import { ActorFollowScoreCache } from '../cache' import { ActorFollowScoreCache } from '../files-cache'
export class ActorFollowScheduler extends AbstractScheduler { export class ActorFollowScheduler extends AbstractScheduler {