fix(backend): fetchInstanceMetadataのLockが永遠に解除されない問題を修正

Co-authored-by: まっちゃとーにゅ <17376330+u1-liquid@users.noreply.github.com>
This commit is contained in:
tamaina 2024-03-03 23:04:33 +00:00
parent 38837bd388
commit 25d5a8cb7e

View file

@ -51,23 +51,33 @@ export class FetchInstanceMetadataService {
} }
@bindThis @bindThis
public async tryLock(host: string): Promise<boolean> { private async tryLock(host: string): Promise<string | null> {
const mutex = await this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '1', 'GET'); // TODO: マイグレーションなのであとで消す (2024.3.1)
return mutex !== '1'; this.redisClient.del(`fetchInstanceMetadata:mutex:${host}`);
return await this.redisClient.set(
`fetchInstanceMetadata:mutex:v2:${host}`, '1',
'EX', 30, // 30秒したら自動でロック解除 https://github.com/misskey-dev/misskey/issues/13506#issuecomment-1975375395
'GET' // 古い値を返すなかったらnull
);
} }
@bindThis @bindThis
public unlock(host: string): Promise<'OK'> { private unlock(host: string): Promise<number> {
return this.redisClient.set(`fetchInstanceMetadata:mutex:${host}`, '0'); return this.redisClient.del(`fetchInstanceMetadata:mutex:v2:${host}`);
} }
@bindThis @bindThis
public async fetchInstanceMetadata(instance: MiInstance, force = false): Promise<void> { public async fetchInstanceMetadata(instance: MiInstance, force = false): Promise<void> {
const host = instance.host; const host = instance.host;
// Acquire mutex to ensure no parallel runs
if (!await this.tryLock(host)) return;
try { try {
if (!force) { if (!force) {
if (await this.tryLock(host) === '1') {
// 1が返ってきていたらロックされている = 何もしない
return;
}
const _instance = await this.federatedInstanceService.fetch(host); const _instance = await this.federatedInstanceService.fetch(host);
const now = Date.now(); const now = Date.now();
if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) { if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) {