Implement cache entry removal queue in diskCache
| @@ -39,6 +39,35 @@ const diskCache = { | ||
| 39 | 39 | */ |
| 40 | 40 | _instance: null, |
| 41 | 41 | /** |
| 42 | + * @type {NodeJS.Timeout?} | |
| 43 | + * @private | |
| 44 | + */ | |
| 45 | + _removalInterval: null, | |
| 46 | + /** | |
| 47 | + * Processes the removal queue. | |
| 48 | + * @returns {Promise<void>} | |
| 49 | + * @private | |
| 50 | + */ | |
| 51 | + _removeCacheEntries: async function() { | |
| 52 | + try { | |
| 53 | + if (!useDiskCache || this.removalQueue.length === 0) { | |
| 54 | + return; | |
| 55 | + } | |
| 56 | + | |
| 57 | + const keys = await diskCache.instance().then(i => i.keys()); | |
| 58 | + for (const item of this.removalQueue) { | |
| 59 | + const key = keys.find(k => k.startsWith(item)); | |
| 60 | + if (key) { | |
| 61 | + await diskCache.instance().then(i => i.removeItem(key)); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + console.info('Removed cache entries:', this.removalQueue); | |
| 65 | + this.removalQueue = []; | |
| 66 | + } catch (error) { | |
| 67 | + console.error('Error while removing cache entries:', error); | |
| 68 | + } | |
| 69 | + }, | |
| 70 | + /** | |
| 42 | 71 | * Gets the disk cache instance. |
| 43 | 72 | * @returns {Promise<import('node-persist').LocalStorage>} |
| 44 | 73 | */ |
| @@ -50,8 +79,14 @@ const diskCache = { | ||
| 50 | 79 | const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', 'characters'); |
| 51 | 80 | this._instance = storage.create({ dir: cacheDir, ttl: false }); |
| 52 | 81 | await this._instance.init(); |
| 82 | + this._removalInterval = setInterval(this._removeCacheEntries.bind(this), 60000); | |
| 53 | 83 | return this._instance; |
| 54 | 84 | }, |
| 85 | + /** | |
| 86 | + * Queue for removal of cache entries. | |
| 87 | + * @type {string[]} | |
| 88 | + */ | |
| 89 | + removalQueue: [], | |
| 55 | 90 | }; |
| 56 | 91 | |
| 57 | 92 | /** |
| @@ -131,15 +166,8 @@ async function writeCharacterData(inputFile, data, outputFile, request, crop = u | ||
| 131 | 166 | } |
| 132 | 167 | } |
| 133 | 168 | if (useDiskCache && !Buffer.isBuffer(inputFile)) { |
| 134 | - const keys = await diskCache.instance().then(i => i.keys()); | |
| 169 | + diskCache.removalQueue.push(inputFile); | |
| 135 | - for (const key of keys) { | |
| 136 | - if (key.startsWith(inputFile)) { | |
| 137 | - await diskCache.instance().then(i => i.removeItem(key)); | |
| 138 | - break; | |
| 139 | 170 | } |
| 140 | - } | |
| 141 | - } | |
| 142 | - | |
| 143 | 171 | /** |
| 144 | 172 | * Read the image, resize, and save it as a PNG into the buffer. |
| 145 | 173 | * @returns {Promise<Buffer>} Image buffer |