diff options
| author | Yuriha <121590760+yuriha-chan@users.noreply.github.com> | 2023-07-07 23:28:27 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-07 23:28:27 +0900 |
| commit | 4c879b3a336aee944cf611a9d01649d62a00d622 (patch) | |
| tree | 4a5c6a305bf103a51758d0c7f671b0928268e730 /packages/backend/src/core/FetchInstanceMetadataService.ts | |
| parent | fix(client): ZenUIでポップアップの表示位置がおかしい問題... (diff) | |
| download | sharkey-4c879b3a336aee944cf611a9d01649d62a00d622.tar.gz sharkey-4c879b3a336aee944cf611a9d01649d62a00d622.tar.bz2 sharkey-4c879b3a336aee944cf611a9d01649d62a00d622.zip | |
perf(backend): Improve performance of FetchInstanceMetadata (#11128)
* Perf: Avoid retries to acquire lock in fetchInstanceMetadata
* Fix
* Add Changelog
* Fix typo
* Fix lint
* 記法をMisskey式にする
* ????
* refactor
https://github.com/misskey-dev/misskey/pull/11128#pullrequestreview-1518059366
* refactor
* getいらない?
* fix
* fix
* Update CHANGELOG.md
* clean up
---------
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Diffstat (limited to 'packages/backend/src/core/FetchInstanceMetadataService.ts')
| -rw-r--r-- | packages/backend/src/core/FetchInstanceMetadataService.ts | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 9de633350b..96ee77d056 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -3,8 +3,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { JSDOM } from 'jsdom'; import tinycolor from 'tinycolor2'; import type { Instance } from '@/models/entities/Instance.js'; -import type { InstancesRepository } from '@/models/index.js'; -import { AppLockService } from '@/core/AppLockService.js'; import type Logger from '@/logger.js'; import { DI } from '@/di-symbols.js'; import { LoggerService } from '@/core/LoggerService.js'; @@ -12,6 +10,7 @@ import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import type { DOMWindow } from 'jsdom'; +import * as Redis from 'ioredis'; type NodeInfo = { openRegistrations?: unknown; @@ -37,33 +36,43 @@ export class FetchInstanceMetadataService { private logger: Logger; constructor( - @Inject(DI.instancesRepository) - private instancesRepository: InstancesRepository, - - private appLockService: AppLockService, private httpRequestService: HttpRequestService, private loggerService: LoggerService, private federatedInstanceService: FederatedInstanceService, + @Inject(DI.redis) + private redisClient: Redis.Redis, ) { this.logger = this.loggerService.getLogger('metadata', 'cyan'); } @bindThis + public async tryLock(host: string): Promise<boolean> { + const mutex = await this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '1', 'GET'); + return mutex !== '1'; + } + + @bindThis + public unlock(host: string): Promise<'OK'> { + return this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '0'); + } + + @bindThis public async fetchInstanceMetadata(instance: Instance, force = false): Promise<void> { - const unlock = await this.appLockService.getFetchInstanceMetadataLock(instance.host); - - if (!force) { - const _instance = await this.instancesRepository.findOneBy({ host: instance.host }); - const now = Date.now(); - if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) { - unlock(); - return; + const host = instance.host; + // Acquire mutex to ensure no parallel runs + if (!await this.tryLock(host)) return; + try { + if (!force) { + const _instance = await this.federatedInstanceService.fetch(host); + const now = Date.now(); + if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) { + // unlock at the finally caluse + return; + } } - } - this.logger.info(`Fetching metadata of ${instance.host} ...`); + this.logger.info(`Fetching metadata of ${instance.host} ...`); - try { const [info, dom, manifest] = await Promise.all([ this.fetchNodeinfo(instance).catch(() => null), this.fetchDom(instance).catch(() => null), @@ -104,7 +113,7 @@ export class FetchInstanceMetadataService { } catch (e) { this.logger.error(`Failed to update metadata of ${instance.host}: ${e}`); } finally { - unlock(); + await this.unlock(host); } } |