From 174e6130ee7fd4337cdcc21613dc1485d7e745e1 Mon Sep 17 00:00:00 2001 From: Daniel Salazar Date: Mon, 29 Dec 2025 16:38:57 -0800 Subject: [PATCH] fix: cache get_app result with expiry to lessen load on db (#2229) * fix: cache get_app result with expiry to lessen load on db * fix: use EX instead --- extensions/api.d.ts | 2 +- src/backend/src/helpers.js | 41 ++++++++++++++++---------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/extensions/api.d.ts b/extensions/api.d.ts index 9fa9528a3..c5db4d771 100644 --- a/extensions/api.d.ts +++ b/extensions/api.d.ts @@ -129,7 +129,7 @@ export interface ExtensionEventTypeMap { domain: string; protocol: string; api_base_url: string; - app?: unknown; + app?: { name: string, uid: string } & Record; [key: string]: unknown; }; }; diff --git a/src/backend/src/helpers.js b/src/backend/src/helpers.js index a9785187e..a2fc30a43 100644 --- a/src/backend/src/helpers.js +++ b/src/backend/src/helpers.js @@ -278,7 +278,7 @@ async function refresh_associations_cache () { // Default file association entries were added with empty types; // this prevents those from showing up. if ( ext === '' ) continue; - if ( ! lists.hasOwnProperty(ext) ) lists[ext] = []; + if ( ! Object.prototype.hasOwnProperty.call(lists, ext) ) lists[ext] = []; lists[ext].push(association.app_id); } @@ -298,7 +298,7 @@ async function get_app (options) { const db = services.get('database').get(DB_READ, 'apps'); const log = services.get('log-service').create('get_app'); - let app = []; + let app; // This condition should be updated if the code below is re-ordered. if ( options.follow_old_names && !options.uid && options.name ) { @@ -315,42 +315,40 @@ async function get_app (options) { if ( options.uid ) { // try cache first - app[0] = kv.get(`apps:uid:${options.uid}`); + app = kv.get(`apps:uid:${options.uid}`); // not in cache, try db - if ( ! app[0] ) { + if ( ! app ) { log.cache(false, `apps:uid:${ options.uid}`); - app = await db.read('SELECT * FROM `apps` WHERE `uid` = ? LIMIT 1', [options.uid]); + app = (await db.read('SELECT * FROM `apps` WHERE `uid` = ? LIMIT 1', [options.uid]))[0]; } } else if ( options.name ) { // try cache first - app[0] = kv.get(`apps:name:${options.name}`); + app = kv.get(`apps:name:${options.name}`); // not in cache, try db - if ( ! app[0] ) { + if ( ! app ) { log.cache(false, `apps:name:${ options.name}`); - app = await db.read('SELECT * FROM `apps` WHERE `name` = ? LIMIT 1', [options.name]); + app = (await db.read('SELECT * FROM `apps` WHERE `name` = ? LIMIT 1', [options.name]))[0]; } } else if ( options.id ) { // try cache first - app[0] = kv.get(`apps:id:${options.id}`); + app = kv.get(`apps:id:${options.id}`); // not in cache, try db - if ( ! app[0] ) { + if ( ! app ) { log.cache(false, `apps:id:${ options.id}`); - app = await db.read('SELECT * FROM `apps` WHERE `id` = ? LIMIT 1', [options.id]); + app = (await db.read('SELECT * FROM `apps` WHERE `id` = ? LIMIT 1', [options.id]))[0]; } } - app = app && app[0] ? app[0] : null; - - if ( app === null ) return null; - - // kv.set(`apps:uid:${app.uid}`, app, { EX: 30 }); - // kv.set(`apps:name:${app.name}`, app, { EX: 30 }); - // kv.set(`apps:id:${app.id}`, app, { EX: 30 }); + if ( ! app ) return null; // shallow clone because we use the `delete` operator // and it corrupts the cache otherwise app = { ...app }; - return new object_returned_by_get_app(app); + kv.set(`apps:uid:${app.uid}`, app, { EX: 30 }); + kv.set(`apps:name:${app.name}`, app, { EX: 30 }); + kv.set(`apps:id:${app.id}`, app, { EX: 30 }); + + return app; } /** @@ -926,11 +924,6 @@ function isString (variable) { return typeof variable === 'string' || variable instanceof String; } -// checks to see if given variable is an object -function isObject (variable) { - return variable !== null && typeof variable === 'object'; -} - /** * Recusrively deletes all files under `path` *