From 3e7ab07b3caa91c9caff7aeb072cf26f2e13ffc9 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Sun, 25 May 2025 08:44:45 -0400 Subject: avoid race conditions in meta / instance insert --- .../backend/src/core/FederatedInstanceService.ts | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'packages/backend/src/core/FederatedInstanceService.ts') diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index e31d802e8c..662c7f7f2d 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -5,15 +5,13 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Redis from 'ioredis'; -import { DataSource, QueryFailedError } from 'typeorm'; import type { InstancesRepository } from '@/models/_.js'; -import { MiInstance } from '@/models/Instance.js'; +import type { MiInstance } from '@/models/Instance.js'; import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; -import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; @Injectable() export class FederatedInstanceService implements OnApplicationShutdown { @@ -26,9 +24,6 @@ export class FederatedInstanceService implements OnApplicationShutdown { @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, - @Inject(DI.db) - private readonly db: DataSource, - private utilityService: UtilityService, private idService: IdService, ) { @@ -58,11 +53,11 @@ export class FederatedInstanceService implements OnApplicationShutdown { const cached = await this.federatedInstanceCache.get(host); if (cached) return cached; - return await this.db.transaction(async tem => { - let index = await tem.findOneBy(MiInstance, { host }); - - if (index == null) { - await tem.insert(MiInstance, { + let index = await this.instancesRepository.findOneBy({ host }); + if (index == null) { + await this.instancesRepository.createQueryBuilder('instance') + .insert() + .values({ id: this.idService.gen(), host, firstRetrievedAt: new Date(), @@ -71,14 +66,15 @@ export class FederatedInstanceService implements OnApplicationShutdown { isMediaSilenced: this.utilityService.isMediaSilencedHost(host), isAllowListed: this.utilityService.isAllowListedHost(host), isBubbled: this.utilityService.isBubbledHost(host), - }); + }) + .orIgnore() + .execute(); - index = await tem.findOneByOrFail(MiInstance, { host }); - } + index = await this.instancesRepository.findOneByOrFail({ host }); + } - await this.federatedInstanceCache.set(host, index); - return index; - }); + await this.federatedInstanceCache.set(host, index); + return index; } @bindThis -- cgit v1.2.3-freya