| 32 | 32 | const useShallowCharacters = !!getConfigValue('performance.lazyLoadCharacters', false, 'boolean'); |
| 33 | 33 | const useDiskCache = !!getConfigValue('performance.useDiskCache', true, 'boolean'); |
| 34 | 34 | |
| 35 | 35 | const diskCacheclass =DiskCache { |
| 36 | | - /** |
| 36 | + /** @type {string} */ |
| 37 | | - * @type {import('node-persist').LocalStorage?} |
| 37 | + static DIRECTORY = 'characters'; |
| 38 | | - * @private |
| 38 | + |
| 39 | | - */ |
| 39 | + /** @type {number} */ |
| 40 | | - _instance: null, |
| 40 | + static REMOVAL_INTERVAL = 60000; |
| 41 | + |
| 42 | + /** @type {import('node-persist').LocalStorage} */ |
| 43 | + #instance; |
| 44 | + |
| 45 | + /** @type {NodeJS.Timeout} */ |
| 46 | + #removalInterval; |
| 47 | + |
| 41 | 48 | /** |
| 42 | | - * @type {NodeJS.Timeout?} |
| 49 | + * Queue for removal of cache entries. |
| 43 | | - * @private |
| 50 | + * @type {Set<string>} |
| 44 | 51 | */ |
| 45 | | - _removalInterval: null, |
| 52 | + removalQueue = new Set(); |
| 53 | + |
| 46 | 54 | /** |
| 47 | 55 | * Processes the removal queue. |
| 48 | 56 | * @returns {Promise<void>} |
| 49 | | - * @private |
| 50 | 57 | */ |
| 51 | 58 | _removeCacheEntries: async function#removeCacheEntries() { |
| 52 | 59 | try { |
| 53 | 60 | if (!useDiskCache || this.removalQueue.size === 0) { |
| 54 | 61 | return; |
| 55 | 62 | } |
| 56 | 63 | |
| 57 | 64 | const keys = await diskCachethis.instance().then(i => i.keys()); |
| 58 | 65 | for (const item of this.removalQueue) { |
| 59 | 66 | const key = keys.find(k => k.startsWith(item)); |
| 60 | 67 | if (key) { |
| 61 | 68 | await diskCachethis.instance().then(i => i.removeItem(key)); |
| 62 | 69 | } |
| 63 | 70 | } |
| 64 | 71 | this.removalQueue.clear(); |
| 65 | 72 | } catch (error) { |
| 66 | 73 | console.error('Error while removing cache entries:', error); |
| 67 | 74 | } |
| 68 | 75 | },; |
| 76 | + |
| 69 | 77 | /** |
| 70 | 78 | * Gets the disk cache instance. |
| 71 | 79 | * @returns {Promise<import('node-persist').LocalStorage>} |
| 72 | 80 | */ |
| 73 | 81 | instance: async functioninstance() { |
| 74 | 82 | if (this._instance#instance) { |
| 75 | 83 | return this._instance#instance; |
| 76 | 84 | } |
| 77 | 85 | |
| 78 | 86 | const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', 'characters'DiskCache.DIRECTORY); |
| 79 | 87 | this._instance#instance = storage.create({ dir: cacheDir, ttl: false }); |
| 80 | 88 | await this._instance#instance.init(); |
| 81 | 89 | this._removalInterval#removalInterval = setInterval(this._removeCacheEntries#removeCacheEntries.bind(this), 60000DiskCache.REMOVAL_INTERVAL); |
| 82 | 90 | return this._instance#instance; |
| 83 | 91 | }, |
| 84 | | - /** |
| 85 | | - * Queue for removal of cache entries. |
| 86 | | - * @type {Set<string>} |
| 87 | | - */ |
| 88 | | - removalQueue: new Set(), |
| 89 | | -}; |
| 90 | 92 | |
| 91 | 93 | /** |
| 92 | 94 | * Verifies disk cache size and prunes it if necessary. |
| 93 | 95 | * @param {import('../users.js').UserDirectoryList[]} directoriesList List of user directories |
| 94 | 96 | * @returns {Promise<void>} |
| 95 | 97 | */ |
| 96 | 98 | export async function verifyCharactersDiskCacheverify(directoriesList) { |
| 97 | 99 | if (!useDiskCache) { |
| 98 | 100 | return; |
| 99 | 101 | } |
| 100 | 102 | |
| 101 | 103 | const cache = await diskCachethis.instance(); |
| 102 | 104 | const validKeys = []; |
| 103 | 105 | for (const dir of directoriesList) { |
| 104 | 106 | const files = fs.readdirSync(dir.characters); |