From 9f6be8d5572ba33588c94789cd350a2f71acd30e Mon Sep 17 00:00:00 2001 From: Johann150 Date: Mon, 14 Nov 2022 22:12:32 +0100 Subject: [PATCH] server: refactor meta caching This removes the "caching" that re-fetches the instance meta information from the database every 10 seconds. --- packages/backend/src/misc/fetch-meta.ts | 68 +++++++++---------- .../server/api/endpoints/admin/update-meta.ts | 21 ++---- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/packages/backend/src/misc/fetch-meta.ts b/packages/backend/src/misc/fetch-meta.ts index e855ac28e..b7fd105a9 100644 --- a/packages/backend/src/misc/fetch-meta.ts +++ b/packages/backend/src/misc/fetch-meta.ts @@ -1,44 +1,44 @@ +import push from 'web-push'; import { db } from '@/db/postgre.js'; import { Meta } from '@/models/entities/meta.js'; +import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js'; let cache: Meta; +/** + * Performs the primitive database operation to set the server configuration + */ +export async function setMeta(meta: Meta): Promise { + const unlock = await getFetchInstanceMetadataLock('localhost'); + + // try to mitigate older bugs where multiple meta entries may have been created + db.manager.clear(Meta); + db.manager.insert(Meta, meta); + + unlock(); +} + +/** + * Performs the primitive database operation to fetch server configuration. + * Writes to `cache` instead of returning. + */ +async function getMeta(): Promise { + const unlock = await getFetchInstanceMetadataLock('localhost'); + + // new IDs are prioritised because multiple records may have been created due to past bugs + cache = db.manager.findOne(Meta, { + order: { + id: 'DESC', + }, + }); + + unlock(); +} + export async function fetchMeta(noCache = false): Promise { if (!noCache && cache) return cache; - return await db.transaction(async transactionalEntityManager => { - // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する - const metas = await transactionalEntityManager.find(Meta, { - order: { - id: 'DESC', - }, - }); + await getMeta(); - const meta = metas[0]; - - if (meta) { - cache = meta; - return meta; - } else { - // metaが空のときfetchMetaが同時に呼ばれるとここが同時に呼ばれてしまうことがあるのでフェイルセーフなupsertを使う - const saved = await transactionalEntityManager - .upsert( - Meta, - { - id: 'x', - }, - ['id'], - ) - .then((x) => transactionalEntityManager.findOneByOrFail(Meta, x.identifiers[0])); - - cache = saved; - return saved; - } - }); + return cache; } - -setInterval(() => { - fetchMeta(true).then(meta => { - cache = meta; - }); -}, 1000 * 10); diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index 93b261c18..e83252c29 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -1,6 +1,5 @@ -import { Meta } from '@/models/entities/meta.js'; import { insertModerationLog } from '@/services/insert-moderation-log.js'; -import { db } from '@/db/postgre.js'; +import { fetchMeta, setMeta } from '@/misc/fetch-meta.js'; import define from '../../define.js'; export const meta = { @@ -375,20 +374,10 @@ export default define(meta, paramDef, async (ps, me) => { set.deeplIsPro = ps.deeplIsPro; } - await db.transaction(async transactionalEntityManager => { - const metas = await transactionalEntityManager.find(Meta, { - order: { - id: 'DESC', - }, - }); - - const meta = metas[0]; - - if (meta) { - await transactionalEntityManager.update(Meta, meta.id, set); - } else { - await transactionalEntityManager.save(Meta, set); - } + const meta = await fetchMeta(); + await setMeta({ + ...meta, + ...set, }); insertModerationLog(me, 'updateMeta');