diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 6fde9ef11..de64a4305 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -31,6 +31,7 @@ import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { truncate } from '@/misc/truncate.js'; import { StatusError } from '@/misc/fetch.js'; import { uriPersonCache } from '@/services/user-cache.js'; +import { publishInternalEvent } from '@/services/stream.js'; const logger = apLogger; @@ -359,6 +360,8 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint location: person['vcard:Address'] || null, }); + publishInternalEvent('remoteUserUpdated', { id: exist.id }); + // ハッシュタグ更新 updateUsertags(exist, tags); diff --git a/packages/backend/src/remote/activitypub/perform.ts b/packages/backend/src/remote/activitypub/perform.ts index 230d94f87..a3c10ba94 100644 --- a/packages/backend/src/remote/activitypub/perform.ts +++ b/packages/backend/src/remote/activitypub/perform.ts @@ -1,7 +1,17 @@ import { IObject } from './type.js'; import { CacheableRemoteUser } from '@/models/entities/user.js'; import { performActivity } from './kernel/index.js'; +import { updatePerson } from './models/person.js'; export default async (actor: CacheableRemoteUser, activity: IObject): Promise => { await performActivity(actor, activity); + + // ついでにリモートユーザーの情報が古かったら更新しておく + if (actor.uri) { + if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { + setImmediate(() => { + updatePerson(actor.uri!); + }); + } + } }; diff --git a/packages/backend/src/server/activitypub/cache.ts b/packages/backend/src/server/activitypub/cache.ts deleted file mode 100644 index eb20d0078..000000000 --- a/packages/backend/src/server/activitypub/cache.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Cache } from "@/misc/cache.js"; -import { User } from "@/models/entities/user.js"; - -export const userCache = new Cache(1000 * 60 * 30); diff --git a/packages/backend/src/server/activitypub/followers.ts b/packages/backend/src/server/activitypub/followers.ts index fdae9dd92..f2bdb48bf 100644 --- a/packages/backend/src/server/activitypub/followers.ts +++ b/packages/backend/src/server/activitypub/followers.ts @@ -10,7 +10,6 @@ import renderFollowUser from '@/remote/activitypub/renderer/follow-user.js'; import { setResponseType } from '../activitypub.js'; import { Users, Followings, UserProfiles } from '@/models/index.js'; import { LessThan } from 'typeorm'; -import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -28,11 +27,10 @@ export default async (ctx: Router.RouterContext) => { return; } - // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる - const user = await userCache.fetch(userId, () => Users.findOne({ + const user = await Users.findOne({ id: userId, host: null, - }).then(x => x || null)); + }); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/activitypub/following.ts b/packages/backend/src/server/activitypub/following.ts index eb1b7a9d8..16b2b051d 100644 --- a/packages/backend/src/server/activitypub/following.ts +++ b/packages/backend/src/server/activitypub/following.ts @@ -11,7 +11,6 @@ import { setResponseType } from '../activitypub.js'; import { Users, Followings, UserProfiles } from '@/models/index.js'; import { LessThan, FindConditions } from 'typeorm'; import { Following } from '@/models/entities/following.js'; -import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -29,11 +28,10 @@ export default async (ctx: Router.RouterContext) => { return; } - // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる - const user = await userCache.fetch(userId, () => Users.findOne({ + const user = await Users.findOne({ id: userId, host: null, - }).then(x => x || null)); + }); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/activitypub/outbox.ts b/packages/backend/src/server/activitypub/outbox.ts index db2a18efc..450fdea96 100644 --- a/packages/backend/src/server/activitypub/outbox.ts +++ b/packages/backend/src/server/activitypub/outbox.ts @@ -15,7 +15,6 @@ import { Users, Notes } from '@/models/index.js'; import { makePaginationQuery } from '../api/common/make-pagination-query.js'; import { Brackets } from 'typeorm'; import { Note } from '@/models/entities/note.js'; -import { userCache } from './cache.js'; export default async (ctx: Router.RouterContext) => { const userId = ctx.params.user; @@ -36,11 +35,10 @@ export default async (ctx: Router.RouterContext) => { return; } - // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる - const user = await userCache.fetch(userId, () => Users.findOne({ + const user = await Users.findOne({ id: userId, host: null, - }).then(x => x || null)); + }); if (user == null) { ctx.status = 404; diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index a8efd37a7..bea863eb7 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -22,6 +22,7 @@ export interface InternalStreamTypes { userChangeSilencedState: { id: User['id']; isSilenced: User['isSilenced']; }; userChangeModeratorState: { id: User['id']; isModerator: User['isModerator']; }; userTokenRegenerated: { id: User['id']; oldToken: User['token']; newToken: User['token']; }; + remoteUserUpdated: { id: User['id']; }; antennaCreated: Antenna; antennaDeleted: Antenna; antennaUpdated: Antenna; diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index b295534cd..f4b0d5204 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -38,8 +38,6 @@ import { endedPollNotificationQueue } from '@/queue/queues.js'; import { Cache } from '@/misc/cache.js'; import { UserProfile } from '@/models/entities/user-profile.js'; -const usersCache = new Cache(Infinity); - const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5); type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -212,7 +210,7 @@ export default async (user: { id: User['id']; username: User['username']; host: tags = tags.filter(tag => Array.from(tag || '').length <= 128).splice(0, 32); if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { - mentionedUsers.push(await usersCache.fetch(data.reply.userId, () => Users.findOneOrFail(data.reply!.userId))); + mentionedUsers.push(await Users.findOneOrFail(data.reply!.userId)); } if (data.visibility === 'specified') { @@ -225,7 +223,7 @@ export default async (user: { id: User['id']; username: User['username']; host: } if (data.reply && !data.visibleUsers.some(x => x.id === data.reply!.userId)) { - data.visibleUsers.push(await usersCache.fetch(data.reply.userId, () => Users.findOneOrFail(data.reply!.userId))); + data.visibleUsers.push(await Users.findOneOrFail(data.reply!.userId)); } } diff --git a/packages/backend/src/services/user-cache.ts b/packages/backend/src/services/user-cache.ts index fdeceb047..4cf3526b7 100644 --- a/packages/backend/src/services/user-cache.ts +++ b/packages/backend/src/services/user-cache.ts @@ -16,7 +16,8 @@ subsdcriber.on('message', async (_, data) => { switch (type) { case 'userChangeSuspendedState': case 'userChangeSilencedState': - case 'userChangeModeratorState': { + case 'userChangeModeratorState': + case 'remoteUserUpdated': { const user = await Users.findOneOrFail(body.id); userByIdCache.set(user.id, user); for (const [k, v] of uriPersonCache.cache.entries()) {