Optimize cache verification

b625319f0cca5f25da1550362e57d8185d635df2

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +25 -11Showing whitespace changes
src/endpoints/characters.js+25 -11
@@ -43,7 +43,7 @@ class DiskCache {
43 static DIRECTORY = 'characters';43 static DIRECTORY = 'characters';
4444
45 /** @type {number} */45 /** @type {number} */
46 static REMOVAL_INTERVAL = 60000;46 static REMOVAL_INTERVAL = 60 * 1000;
4747
48 /** @type {import('node-persist').LocalStorage} */48 /** @type {import('node-persist').LocalStorage} */
49 #instance;49 #instance;
@@ -58,6 +58,22 @@ class DiskCache {
58 removalQueue = [];58 removalQueue = [];
5959
60 /**60 /**
61 * Path to the cache directory.
62 * @returns {string}
63 */
64 get cachePath() {
65 return path.join(globalThis.DATA_ROOT, '_cache', DiskCache.DIRECTORY);
66 }
67
68 /**
69 * Returns the list of hashed keys in the cache.
70 * @returns {string[]}
71 */
72 get hashedKeys() {
73 return fs.readdirSync(this.cachePath);
74 }
75
76 /**
61 * Processes the removal queue.77 * Processes the removal queue.
62 * @returns {Promise<void>}78 * @returns {Promise<void>}
63 */79 */
@@ -110,8 +126,7 @@ class DiskCache {
110 return this.#instance;126 return this.#instance;
111 }127 }
112128
113 const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', DiskCache.DIRECTORY);129 this.#instance = storage.create({ dir: this.cachePath, ttl: false });
114 this.#instance = storage.create({ dir: cacheDir, ttl: false });
115 await this.#instance.init();130 await this.#instance.init();
116 this.#removalInterval = setInterval(this.#removeCacheEntries.bind(this), DiskCache.REMOVAL_INTERVAL);131 this.#removalInterval = setInterval(this.#removeCacheEntries.bind(this), DiskCache.REMOVAL_INTERVAL);
117 return this.#instance;132 return this.#instance;
@@ -128,18 +143,17 @@ class DiskCache {
128 }143 }
129144
130 const cache = await this.instance();145 const cache = await this.instance();
131 const validKeys = [];146 const validKeys = new Set();
132 for (const dir of directoriesList) {147 for (const dir of directoriesList) {
133 const files = fs.readdirSync(dir.characters);148 const files = fs.readdirSync(dir.characters, { withFileTypes: true });
134 for (const file of files) {149 for (const file of files.filter(f => f.isFile() && path.extname(f.name) === '.png')) {
135 const filePath = path.join(dir.characters, file);150 const filePath = path.join(dir.characters, file.name);
136 const stat = fs.statSync(filePath);151 const stat = fs.statSync(filePath);
137 validKeys.push(`${filePath}-${stat.mtimeMs}`);152 validKeys.add(path.parse(cache.getDatumPath(`${filePath}-${stat.mtimeMs}`)).base);
138 }153 }
139 }154 }
140 const cacheKeys = await cache.keys();155 for (const key of this.hashedKeys) {
141 for (const key of cacheKeys) {156 if (!validKeys.has(key)) {
142 if (!validKeys.includes(key)) {
143 await cache.removeItem(key);157 await cache.removeItem(key);
144 }158 }
145 }159 }