diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-05-25 08:44:45 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-05-28 21:31:40 -0400 |
| commit | 3e7ab07b3caa91c9caff7aeb072cf26f2e13ffc9 (patch) | |
| tree | adc3623c2c0f938f5bb4ac5504ab4df918ec10a4 /packages/backend/src/core/MetaService.ts | |
| parent | remove broken HTTP users before running add_instance_foreign_keys migration (diff) | |
| download | sharkey-3e7ab07b3caa91c9caff7aeb072cf26f2e13ffc9.tar.gz sharkey-3e7ab07b3caa91c9caff7aeb072cf26f2e13ffc9.tar.bz2 sharkey-3e7ab07b3caa91c9caff7aeb072cf26f2e13ffc9.zip | |
avoid race conditions in meta / instance insert
Diffstat (limited to 'packages/backend/src/core/MetaService.ts')
| -rw-r--r-- | packages/backend/src/core/MetaService.ts | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/packages/backend/src/core/MetaService.ts b/packages/backend/src/core/MetaService.ts index 5b6ee8920e..b4ccfec4cc 100644 --- a/packages/backend/src/core/MetaService.ts +++ b/packages/backend/src/core/MetaService.ts @@ -14,6 +14,7 @@ import type { GlobalEvents } from '@/core/GlobalEventService.js'; import { FeaturedService } from '@/core/FeaturedService.js'; import { MiInstance } from '@/models/Instance.js'; import { diffArrays } from '@/misc/diff-arrays.js'; +import type { MetasRepository } from '@/models/_.js'; import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() @@ -28,6 +29,9 @@ export class MetaService implements OnApplicationShutdown { @Inject(DI.db) private db: DataSource, + @Inject(DI.metasRepository) + private readonly metasRepository: MetasRepository, + private featuredService: FeaturedService, private globalEventService: GlobalEventService, ) { @@ -69,35 +73,31 @@ export class MetaService implements OnApplicationShutdown { public async fetch(noCache = false): Promise<MiMeta> { if (!noCache && this.cache) return this.cache; - return await this.db.transaction(async transactionalEntityManager => { - // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する - const metas = await transactionalEntityManager.find(MiMeta, { + // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する + let meta = await this.metasRepository.findOne({ + order: { + id: 'DESC', + }, + }); + + if (!meta) { + await this.metasRepository.createQueryBuilder('meta') + .insert() + .values({ + id: 'x', + }) + .orIgnore() + .execute(); + + meta = await this.metasRepository.findOneOrFail({ order: { id: 'DESC', }, }); + } - const meta = metas[0]; - - if (meta) { - this.cache = meta; - return meta; - } else { - // metaが空のときfetchMetaが同時に呼ばれるとここが同時に呼ばれてしまうことがあるのでフェイルセーフなupsertを使う - const saved = await transactionalEntityManager - .upsert( - MiMeta, - { - id: 'x', - }, - ['id'], - ) - .then((x) => transactionalEntityManager.findOneByOrFail(MiMeta, x.identifiers[0])); - - this.cache = saved; - return saved; - } - }); + this.cache = meta; + return meta; } @bindThis |