リモートユーザーが復活してもキャッシュにより該当ユーザーのActivityが受け入れられないのを修正 Fix #13273 (#13275)

* リモートユーザーが復活してもキャッシュにより該当ユーザーのActivityが受け入れられないのを修正 Fix #13273

* CHAGELOG

* Use Redis event

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
This commit is contained in:
MeiMei 2024-02-16 14:30:53 +09:00 committed by GitHub
parent 40bbae3d6c
commit cfa573a3a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 12 deletions

View file

@ -92,6 +92,7 @@
- Fix: ジョブに関する設定の名前を修正 relashionshipJobPerSec -> relationshipJobPerSec - Fix: ジョブに関する設定の名前を修正 relashionshipJobPerSec -> relationshipJobPerSec
- Fix: コントロールパネル->モデレーション->「誰でも新規登録できるようにする」の初期値をONからOFFに変更 #13122 - Fix: コントロールパネル->モデレーション->「誰でも新規登録できるようにする」の初期値をONからOFFに変更 #13122
- Enhance: 連合向けのノート配信を軽量化 #13192 - Enhance: 連合向けのノート配信を軽量化 #13192
- Fix: リモートユーザーが復活してもキャッシュにより該当ユーザーのActivityが受け入れられないのを修正 #13273
### Service Worker ### Service Worker
- Enhance: オフライン表示のデザインを改善・多言語対応 - Enhance: オフライン表示のデザインを改善・多言語対応

View file

@ -85,6 +85,7 @@ export class CacheService implements OnApplicationShutdown {
this.uriPersonCache = new MemoryKVCache<MiUser | null, string | null>(Infinity, { this.uriPersonCache = new MemoryKVCache<MiUser | null, string | null>(Infinity, {
toMapConverter: user => { toMapConverter: user => {
if (user === null) return null; if (user === null) return null;
if (user.isDeleted) return null;
userByIdCache.set(user.id, user); userByIdCache.set(user.id, user);
return user.id; return user.id;
@ -160,16 +161,25 @@ export class CacheService implements OnApplicationShutdown {
switch (type) { switch (type) {
case 'userChangeSuspendedState': case 'userChangeSuspendedState':
case 'remoteUserUpdated': { case 'remoteUserUpdated': {
const user = await this.usersRepository.findOneByOrFail({ id: body.id }); const user = await this.usersRepository.findOneBy({ id: body.id });
this.userByIdCache.set(user.id, user); if (user == null) {
for (const [k, v] of this.uriPersonCache.cache.entries()) { this.userByIdCache.delete(body.id);
if (v.value === user.id) { for (const [k, v] of this.uriPersonCache.cache.entries()) {
this.uriPersonCache.set(k, user); if (v.value === body.id) {
this.uriPersonCache.delete(k);
}
}
} else {
this.userByIdCache.set(user.id, user);
for (const [k, v] of this.uriPersonCache.cache.entries()) {
if (v.value === user.id) {
this.uriPersonCache.set(k, user);
}
}
if (this.userEntityService.isLocalUser(user)) {
this.localUserByNativeTokenCache.set(user.token!, user);
this.localUserByIdCache.set(user.id, user);
} }
}
if (this.userEntityService.isLocalUser(user)) {
this.localUserByNativeTokenCache.set(user.token!, user);
this.localUserByIdCache.set(user.id, user);
} }
break; break;
} }

View file

@ -106,12 +106,12 @@ export class ApDbResolverService implements OnApplicationShutdown {
return await this.cacheService.userByIdCache.fetchMaybe( return await this.cacheService.userByIdCache.fetchMaybe(
parsed.id, parsed.id,
() => this.usersRepository.findOneBy({ id: parsed.id }).then(x => x ?? undefined), () => this.usersRepository.findOneBy({ id: parsed.id, isDeleted: false }).then(x => x ?? undefined),
) as MiLocalUser | undefined ?? null; ) as MiLocalUser | undefined ?? null;
} else { } else {
return await this.cacheService.uriPersonCache.fetch( return await this.cacheService.uriPersonCache.fetch(
parsed.uri, parsed.uri,
() => this.usersRepository.findOneBy({ uri: parsed.uri }), () => this.usersRepository.findOneBy({ uri: parsed.uri, isDeleted: false }),
) as MiRemoteUser | null; ) as MiRemoteUser | null;
} }
} }
@ -136,8 +136,12 @@ export class ApDbResolverService implements OnApplicationShutdown {
if (key == null) return null; if (key == null) return null;
const user = await this.cacheService.findUserById(key.userId).catch(() => null) as MiRemoteUser | null;
if (user == null) return null;
if (user.isDeleted) return null;
return { return {
user: await this.cacheService.findUserById(key.userId) as MiRemoteUser, user,
key, key,
}; };
} }
@ -151,6 +155,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
key: MiUserPublickey | null; key: MiUserPublickey | null;
} | null> { } | null> {
const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser; const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser;
if (user.isDeleted) return null;
const key = await this.publicKeyByUserIdCache.fetch( const key = await this.publicKeyByUserIdCache.fetch(
user.id, user.id,

View file

@ -35,6 +35,8 @@ import { ApResolverService } from './ApResolverService.js';
import { ApAudienceService } from './ApAudienceService.js'; import { ApAudienceService } from './ApAudienceService.js';
import { ApPersonService } from './models/ApPersonService.js'; import { ApPersonService } from './models/ApPersonService.js';
import { ApQuestionService } from './models/ApQuestionService.js'; import { ApQuestionService } from './models/ApQuestionService.js';
import { CacheService } from '@/core/CacheService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { Resolver } from './ApResolverService.js'; import type { Resolver } from './ApResolverService.js';
import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove } from './type.js'; import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove } from './type.js';
@ -82,6 +84,8 @@ export class ApInboxService {
private apPersonService: ApPersonService, private apPersonService: ApPersonService,
private apQuestionService: ApQuestionService, private apQuestionService: ApQuestionService,
private queueService: QueueService, private queueService: QueueService,
private cacheService: CacheService,
private globalEventService: GlobalEventService,
) { ) {
this.logger = this.apLoggerService.logger; this.logger = this.apLoggerService.logger;
} }
@ -479,6 +483,8 @@ export class ApInboxService {
isDeleted: true, isDeleted: true,
}); });
this.globalEventService.publishInternalEvent('remoteUserUpdated', { id: actor.id });
return `ok: queued ${job.name} ${job.id}`; return `ok: queued ${job.name} ${job.id}`;
} }