mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-31 07:11:33 +00:00
feat: use SimpleDataStore for album pages cache
this should have better lifecycle and use less memory over time, since we can define max items in cache at the moment hard-coded to 10 cached pages (inclusive of nojs version if ever generated)
This commit is contained in:
parent
b9d0f787d7
commit
2ca2fef301
@ -296,7 +296,7 @@ self.disable = async (req, res, next) => {
|
|||||||
.first()
|
.first()
|
||||||
.update('enabled', 0)
|
.update('enabled', 0)
|
||||||
}
|
}
|
||||||
utils.invalidateAlbumsCache([id])
|
utils.deleteStoredAlbumRenders([id])
|
||||||
utils.invalidateStatsCache('albums')
|
utils.invalidateStatsCache('albums')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -387,7 +387,7 @@ self.edit = async (req, res, next) => {
|
|||||||
await utils.db.table('albums')
|
await utils.db.table('albums')
|
||||||
.where(filter)
|
.where(filter)
|
||||||
.update(update)
|
.update(update)
|
||||||
utils.invalidateAlbumsCache([id])
|
utils.deleteStoredAlbumRenders([id])
|
||||||
utils.invalidateStatsCache('albums')
|
utils.invalidateStatsCache('albums')
|
||||||
|
|
||||||
if (req.body.requestLink) {
|
if (req.body.requestLink) {
|
||||||
@ -676,7 +676,7 @@ self.addFiles = async (req, res, next) => {
|
|||||||
await utils.db.table('albums')
|
await utils.db.table('albums')
|
||||||
.whereIn('id', albumids)
|
.whereIn('id', albumids)
|
||||||
.update('editedAt', Math.floor(Date.now() / 1000))
|
.update('editedAt', Math.floor(Date.now() / 1000))
|
||||||
utils.invalidateAlbumsCache(albumids)
|
utils.deleteStoredAlbumRenders(albumids)
|
||||||
|
|
||||||
await res.json({ success: true, failed })
|
await res.json({ success: true, failed })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -317,7 +317,7 @@ self.deleteUser = async (req, res, next) => {
|
|||||||
await utils.db.table('albums')
|
await utils.db.table('albums')
|
||||||
.whereIn('id', albumids)
|
.whereIn('id', albumids)
|
||||||
.del()
|
.del()
|
||||||
utils.invalidateAlbumsCache(albumids)
|
utils.deleteStoredAlbumRenders(albumids)
|
||||||
|
|
||||||
// Unlink their archives
|
// Unlink their archives
|
||||||
await Promise.all(albums.map(async album => {
|
await Promise.all(albums.map(async album => {
|
||||||
|
@ -926,7 +926,7 @@ self.storeFilesToDb = async (req, res, user, infoMap) => {
|
|||||||
await utils.db.table('albums')
|
await utils.db.table('albums')
|
||||||
.whereIn('id', authorizedIds)
|
.whereIn('id', authorizedIds)
|
||||||
.update('editedAt', Math.floor(Date.now() / 1000))
|
.update('editedAt', Math.floor(Date.now() / 1000))
|
||||||
utils.invalidateAlbumsCache(authorizedIds)
|
utils.deleteStoredAlbumRenders(authorizedIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ const perms = require('./permissionController')
|
|||||||
const apiErrorsHandler = require('./handlers/apiErrorsHandler')
|
const apiErrorsHandler = require('./handlers/apiErrorsHandler')
|
||||||
const ClientError = require('./utils/ClientError')
|
const ClientError = require('./utils/ClientError')
|
||||||
const ServerError = require('./utils/ServerError')
|
const ServerError = require('./utils/ServerError')
|
||||||
|
const SimpleDataStore = require('./utils/SimpleDataStore')
|
||||||
const config = require('./../config')
|
const config = require('./../config')
|
||||||
const logger = require('./../logger')
|
const logger = require('./../logger')
|
||||||
|
|
||||||
@ -59,7 +60,6 @@ const self = {
|
|||||||
thumbsSize: config.uploads.generateThumbs.size || 200,
|
thumbsSize: config.uploads.generateThumbs.size || 200,
|
||||||
ffprobe: promisify(ffmpeg.ffprobe),
|
ffprobe: promisify(ffmpeg.ffprobe),
|
||||||
|
|
||||||
albumsCache: {},
|
|
||||||
timezoneOffset: new Date().getTimezoneOffset(),
|
timezoneOffset: new Date().getTimezoneOffset(),
|
||||||
|
|
||||||
retentions: {
|
retentions: {
|
||||||
@ -68,6 +68,10 @@ const self = {
|
|||||||
default: {}
|
default: {}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
albumRenderStore: new SimpleDataStore({
|
||||||
|
limit: 10,
|
||||||
|
strategy: SimpleDataStore.STRATEGIES[0]
|
||||||
|
}),
|
||||||
contentDispositionStore: null
|
contentDispositionStore: null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,7 +682,7 @@ self.bulkDeleteFromDb = async (field, values, user) => {
|
|||||||
.whereIn('id', albumids)
|
.whereIn('id', albumids)
|
||||||
.update('editedAt', Math.floor(Date.now() / 1000))
|
.update('editedAt', Math.floor(Date.now() / 1000))
|
||||||
.catch(logger.error)
|
.catch(logger.error)
|
||||||
self.invalidateAlbumsCache(albumids)
|
self.deleteStoredAlbumRenders(albumids)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Purge Cloudflare's cache if necessary, but do not wait
|
// Purge Cloudflare's cache if necessary, but do not wait
|
||||||
@ -769,10 +773,10 @@ self.bulkDeleteExpired = async (dryrun, verbose) => {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
self.invalidateAlbumsCache = albumids => {
|
self.deleteStoredAlbumRenders = albumids => {
|
||||||
for (const albumid of albumids) {
|
for (const albumid of albumids) {
|
||||||
delete self.albumsCache[albumid]
|
self.albumRenderStore.delete(`${albumid}`)
|
||||||
delete self.albumsCache[`${albumid}-nojs`]
|
self.albumRenderStore.delete(`${albumid}-nojs`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,17 +26,13 @@ routes.get('/a/:identifier', async (req, res, next) => {
|
|||||||
|
|
||||||
let cacheid
|
let cacheid
|
||||||
if (process.env.NODE_ENV !== 'development') {
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
// Cache ID - we initialize a separate cache for No-JS version
|
// Cache ID - we use a separate cache key for No-JS version
|
||||||
cacheid = nojs ? `${album.id}-nojs` : album.id
|
cacheid = `${album.id}${nojs ? '-nojs' : ''}`
|
||||||
|
|
||||||
if (!utils.albumsCache[cacheid]) {
|
const cache = utils.albumRenderStore.get(cacheid)
|
||||||
utils.albumsCache[cacheid] = {
|
if (cache) {
|
||||||
cache: null,
|
return res.send(cache)
|
||||||
generating: false
|
} else if (cache === null) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!utils.albumsCache[cacheid].cache && utils.albumsCache[cacheid].generating) {
|
|
||||||
return res.render('album-notice', {
|
return res.render('album-notice', {
|
||||||
config,
|
config,
|
||||||
utils,
|
utils,
|
||||||
@ -44,11 +40,9 @@ routes.get('/a/:identifier', async (req, res, next) => {
|
|||||||
album,
|
album,
|
||||||
notice: 'This album\'s public page is still being generated. Please try again later.'
|
notice: 'This album\'s public page is still being generated. Please try again later.'
|
||||||
})
|
})
|
||||||
} else if (utils.albumsCache[cacheid].cache) {
|
|
||||||
return res.send(utils.albumsCache[cacheid].cache)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.albumsCache[cacheid].generating = true
|
utils.albumRenderStore.hold(cacheid)
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = await utils.db.table('files')
|
const files = await utils.db.table('files')
|
||||||
@ -90,13 +84,16 @@ routes.get('/a/:identifier', async (req, res, next) => {
|
|||||||
}, (error, html) => {
|
}, (error, html) => {
|
||||||
const data = error ? null : html
|
const data = error ? null : html
|
||||||
if (cacheid) {
|
if (cacheid) {
|
||||||
utils.albumsCache[cacheid].cache = data
|
// Only store rendered page if it did not error out and album actually have files
|
||||||
utils.albumsCache[cacheid].generating = false
|
if (data && files.length) {
|
||||||
|
utils.albumRenderStore.set(cacheid, data)
|
||||||
|
} else {
|
||||||
|
utils.albumRenderStore.delete(cacheid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Express should already send error to the next handler
|
// Express should already send error to the next handler
|
||||||
if (error) return
|
if (!error) return res.send(data)
|
||||||
return res.send(data)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user