Limit user tokens cache
authorChocobozzz <me@florianbigard.com>
Tue, 19 Mar 2019 13:23:17 +0000 (14:23 +0100)
committerChocobozzz <me@florianbigard.com>
Tue, 19 Mar 2019 13:30:43 +0000 (14:30 +0100)
18 files changed:
server.ts
server/controllers/static.ts
server/initializers/constants.ts
server/initializers/installer.ts
server/lib/cache/abstract-video-static-file-cache.ts [deleted file]
server/lib/cache/actor-follow-score-cache.ts [deleted file]
server/lib/cache/index.ts [deleted file]
server/lib/cache/videos-caption-cache.ts [deleted file]
server/lib/cache/videos-preview-cache.ts [deleted file]
server/lib/files-cache/abstract-video-static-file-cache.ts [new file with mode: 0644]
server/lib/files-cache/actor-follow-score-cache.ts [new file with mode: 0644]
server/lib/files-cache/index.ts [new file with mode: 0644]
server/lib/files-cache/videos-caption-cache.ts [new file with mode: 0644]
server/lib/files-cache/videos-preview-cache.ts [new file with mode: 0644]
server/lib/job-queue/handlers/activitypub-http-broadcast.ts
server/lib/job-queue/handlers/activitypub-http-unicast.ts
server/lib/oauth-model.ts
server/lib/schedulers/actor-follow-scheduler.ts

index 9fe7411755db749c35f8194754a8b62ed5578f7f..df56bcd822ad3602a974a65821eb966fe2523144 100644 (file)
--- a/server.ts
+++ b/server.ts
@@ -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)
 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()
 if (missed.length !== 0) {
@@ -82,7 +82,7 @@ migrate()
 import { installApplication } from './server/initializers'
 import { Emailer } from './server/lib/emailer'
 import { JobQueue } from './server/lib/job-queue'
-import { VideosPreviewCache, VideosCaptionCache } from './server/lib/cache'
+import { VideosPreviewCache, VideosCaptionCache } from './server/lib/files-cache'
 import {
   activityPubRouter,
   apiRouter,
@@ -218,8 +218,8 @@ async function startApplication () {
   ])
 
   // Caches initializations
-  VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE)
-  VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, CACHE.VIDEO_CAPTIONS.MAX_AGE)
+  VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, FILES_CACHE.PREVIEWS.MAX_AGE)
+  VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE)
 
   // Enable Schedulers
   ActorFollowScheduler.Instance.enable()
index 7b14320e45c6ef2a90e0ae08ad1698f180910f9d..e65c7afd3991382310f1bb40d54b44c99bc4c94f 100644 (file)
@@ -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'
index 7fac8a4d6f68c59512e92a905fe66b97909b28c2..7a3ec387415762deba0e8ef2afdb1b115b8ec456 100644 (file)
@@ -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,
index cd2c942fd1dc2851136989782f72b0421138004c..07af96b68982fc16fb3a300151863b218326c2ac 100644 (file)
@@ -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<any>[] = []
 
@@ -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<void>[] = []
   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 (file)
index 7512f2b..0000000
+++ /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 <T> {
-
-  protected lru
-
-  abstract getFilePath (params: T): Promise<string>
-
-  // Load and save the remote file, then return the local path from filesystem
-  protected abstract loadRemoteFile (key: string): Promise<string>
-
-  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<string>((res, rej) => {
-      this.lru.get(key, (err, value) => {
-        err ? rej(err) : res(value)
-      })
-    })
-  }
-
-  protected saveRemoteVideoFileAndReturnPath (video: VideoModel, remoteStaticPath: string, destPath: string) {
-    return new Promise<string>((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 (file)
index d070bde..0000000
+++ /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 (file)
index e921d04..0000000
+++ /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 (file)
index f240aff..0000000
+++ /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 <GetPathParam> {
-
-  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 (file)
index a5d6f5b..0000000
+++ /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 <string> {
-
-  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 (file)
index 0000000..7512f2b
--- /dev/null
@@ -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 <T> {
+
+  protected lru
+
+  abstract getFilePath (params: T): Promise<string>
+
+  // Load and save the remote file, then return the local path from filesystem
+  protected abstract loadRemoteFile (key: string): Promise<string>
+
+  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<string>((res, rej) => {
+      this.lru.get(key, (err, value) => {
+        err ? rej(err) : res(value)
+      })
+    })
+  }
+
+  protected saveRemoteVideoFileAndReturnPath (video: VideoModel, remoteStaticPath: string, destPath: string) {
+    return new Promise<string>((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 (file)
index 0000000..d070bde
--- /dev/null
@@ -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 (file)
index 0000000..e921d04
--- /dev/null
@@ -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 (file)
index 0000000..fe5b441
--- /dev/null
@@ -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 <GetPathParam> {
+
+  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 (file)
index 0000000..01cd364
--- /dev/null
@@ -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 <string> {
+
+  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
+}
index 9493945ff6d9b0aadfc2514c2b4e0cb09b74ccef..2b1e21c3939c3518ceaef2d74fe101cf8fced4f2 100644 (file)
@@ -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[]
index 3973dcdc8cc7dced56a3977a6e916b99cc24b612..59de7119ade7f0fd14a8f3c68b9cce999dac52ca 100644 (file)
@@ -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
index 2cd2ae97cf6c9978837f4ac054d4d968a64e205b..5b4a2bcf9e3013dcc4db51a5b42cb57285c28141 100644 (file)
@@ -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
       }
index 3967be7f8f41981c7fac75b72e3c6df8a31b7957..05e6bd139e2e1fe28b3bdebb678294ff1eeff4b2 100644 (file)
@@ -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 {