use cache in NotificationEntityService
This commit is contained in:
parent
b3b08e2315
commit
3fc17fd0ee
4 changed files with 36 additions and 36 deletions
|
|
@ -95,7 +95,10 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
data: Omit<FilterUnionByProperty<MiNotification, 'type', T>, 'type' | 'id' | 'createdAt' | 'notifierId'>,
|
||||
notifierId?: MiUser['id'] | null,
|
||||
): Promise<MiNotification | null> {
|
||||
const profile = await this.cacheService.userProfileCache.fetch(notifieeId);
|
||||
const [profile, notifiee] = await Promise.all([
|
||||
this.cacheService.userProfileCache.fetch(notifieeId),
|
||||
this.cacheService.findUserById(notifieeId),
|
||||
]);
|
||||
|
||||
// 古いMisskeyバージョンのキャッシュが残っている可能性がある
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
|
|
@ -179,7 +182,7 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} while (true);
|
||||
|
||||
const packed = await this.notificationEntityService.pack(notification, notifieeId, {});
|
||||
const packed = await this.notificationEntityService.pack(notification, notifiee, {});
|
||||
|
||||
if (packed == null) return null;
|
||||
|
||||
|
|
@ -196,8 +199,8 @@ export class NotificationService implements OnApplicationShutdown {
|
|||
this.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed);
|
||||
this.pushNotificationService.pushNotification(notifieeId, 'notification', packed);
|
||||
|
||||
if (type === 'follow') this.emailNotificationFollow(notifieeId, await this.usersRepository.findOneByOrFail({ id: notifierId! }));
|
||||
if (type === 'receiveFollowRequest') this.emailNotificationReceiveFollowRequest(notifieeId, await this.usersRepository.findOneByOrFail({ id: notifierId! }));
|
||||
if (type === 'follow') this.emailNotificationFollow(notifieeId, await this.cacheService.findUserById(notifierId!));
|
||||
if (type === 'receiveFollowRequest') this.emailNotificationReceiveFollowRequest(notifieeId, await this.cacheService.findUserById(notifierId!));
|
||||
}, () => { /* aborted, ignore it */ });
|
||||
|
||||
return notification;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
*/
|
||||
async #packInternal <T extends MiNotification | MiGroupedNotification> (
|
||||
src: T,
|
||||
meId: MiUser['id'],
|
||||
me: MiUser,
|
||||
options: {
|
||||
checkValidNotifier?: boolean;
|
||||
},
|
||||
|
|
@ -80,13 +80,13 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
): Promise<Packed<'Notification'> | null> {
|
||||
const notification = src;
|
||||
|
||||
if (options.checkValidNotifier !== false && !(await this.#isValidNotifier(notification, meId))) return null;
|
||||
if (options.checkValidNotifier !== false && !(await this.#isValidNotifier(notification, me.id))) return null;
|
||||
|
||||
const needsNote = NOTE_REQUIRED_NOTIFICATION_TYPES.has(notification.type) && 'noteId' in notification;
|
||||
const noteIfNeed = needsNote ? (
|
||||
hint?.packedNotes != null
|
||||
? hint.packedNotes.get(notification.noteId)
|
||||
: undefOnMissing(this.noteEntityService.pack(notification.noteId, { id: meId }, {
|
||||
: undefOnMissing(this.noteEntityService.pack(notification.noteId, me, {
|
||||
detail: true,
|
||||
}))
|
||||
) : undefined;
|
||||
|
|
@ -97,7 +97,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
const userIfNeed = needsUser ? (
|
||||
hint?.packedUsers != null
|
||||
? hint.packedUsers.get(notification.notifierId)
|
||||
: undefOnMissing(this.userEntityService.pack(notification.notifierId, { id: meId }))
|
||||
: undefOnMissing(this.userEntityService.pack(notification.notifierId, me))
|
||||
) : undefined;
|
||||
// if the user has been deleted, don't show this notification
|
||||
if (needsUser && !userIfNeed) return null;
|
||||
|
|
@ -107,7 +107,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
const reactions = (await Promise.all(notification.reactions.map(async reaction => {
|
||||
const user = hint?.packedUsers != null
|
||||
? hint.packedUsers.get(reaction.userId)!
|
||||
: await undefOnMissing(this.userEntityService.pack(reaction.userId, { id: meId }));
|
||||
: await undefOnMissing(this.userEntityService.pack(reaction.userId, me));
|
||||
return {
|
||||
user,
|
||||
reaction: reaction.reaction,
|
||||
|
|
@ -132,7 +132,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
return packedUser;
|
||||
}
|
||||
|
||||
return undefOnMissing(this.userEntityService.pack(userId, { id: meId }));
|
||||
return undefOnMissing(this.userEntityService.pack(userId, me));
|
||||
}))).filter(x => x != null);
|
||||
// if all users have been deleted, don't show this notification
|
||||
if (users.length === 0) {
|
||||
|
|
@ -159,7 +159,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
}
|
||||
|
||||
const needsChatRoomInvitation = notification.type === 'chatRoomInvitationReceived';
|
||||
const chatRoomInvitation = needsChatRoomInvitation ? await this.chatEntityService.packRoomInvitation(notification.invitationId, { id: meId }).catch(() => null) : undefined;
|
||||
const chatRoomInvitation = needsChatRoomInvitation ? await this.chatEntityService.packRoomInvitation(notification.invitationId, me).catch(() => null) : undefined;
|
||||
// if the invitation has been deleted, don't show this notification
|
||||
if (needsChatRoomInvitation && !chatRoomInvitation) {
|
||||
return null;
|
||||
|
|
@ -212,20 +212,20 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
|
||||
async #packManyInternal <T extends MiNotification | MiGroupedNotification> (
|
||||
notifications: T[],
|
||||
meId: MiUser['id'],
|
||||
me: MiUser,
|
||||
): Promise<T[]> {
|
||||
if (notifications.length === 0) return [];
|
||||
|
||||
let validNotifications = notifications;
|
||||
|
||||
validNotifications = await this.#filterValidNotifier(validNotifications, meId);
|
||||
validNotifications = await this.#filterValidNotifier(validNotifications, me.id);
|
||||
|
||||
const noteIds = validNotifications.map(x => 'noteId' in x ? x.noteId : null).filter(x => x != null);
|
||||
const notes = noteIds.length > 0 ? await this.notesRepository.find({
|
||||
where: { id: In(noteIds) },
|
||||
relations: ['user', 'reply', 'reply.user', 'renote', 'renote.user'],
|
||||
relations: ['user', 'reply', 'reply.user', 'renote', 'renote.user', 'renote.reply'],
|
||||
}) : [];
|
||||
const packedNotesArray = await this.noteEntityService.packMany(notes, { id: meId }, {
|
||||
const packedNotesArray = await this.noteEntityService.packMany(notes, me, {
|
||||
detail: true,
|
||||
});
|
||||
const packedNotes = new Map(packedNotesArray.map(p => [p.id, p]));
|
||||
|
|
@ -238,10 +238,8 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
if (notification.type === 'reaction:grouped') userIds.push(...notification.reactions.map(x => x.userId));
|
||||
if (notification.type === 'renote:grouped') userIds.push(...notification.userIds);
|
||||
}
|
||||
const users = userIds.length > 0 ? await this.usersRepository.find({
|
||||
where: { id: In(userIds) },
|
||||
}) : [];
|
||||
const packedUsersArray = await this.userEntityService.packMany(users, { id: meId });
|
||||
const users = await this.cacheService.getUsers(userIds);
|
||||
const packedUsersArray = await this.userEntityService.packMany(Array.from(users.values()), me);
|
||||
const packedUsers = new Map(packedUsersArray.map(p => [p.id, p]));
|
||||
|
||||
// 既に解決されたフォローリクエストの通知を除外
|
||||
|
|
@ -256,7 +254,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
const packPromises = validNotifications.map(x => {
|
||||
return this.pack(
|
||||
x,
|
||||
meId,
|
||||
me,
|
||||
{ checkValidNotifier: false },
|
||||
{ packedNotes, packedUsers },
|
||||
);
|
||||
|
|
@ -268,7 +266,7 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
@bindThis
|
||||
public async pack(
|
||||
src: MiNotification | MiGroupedNotification,
|
||||
meId: MiUser['id'],
|
||||
me: MiUser,
|
||||
|
||||
options: {
|
||||
checkValidNotifier?: boolean;
|
||||
|
|
@ -278,23 +276,23 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
packedUsers: Map<MiUser['id'], Packed<'UserLite'>>;
|
||||
},
|
||||
): Promise<Packed<'Notification'> | null> {
|
||||
return await this.#packInternal(src, meId, options, hint);
|
||||
return await this.#packInternal(src, me, options, hint);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async packMany(
|
||||
notifications: MiNotification[],
|
||||
meId: MiUser['id'],
|
||||
me: MiUser,
|
||||
): Promise<MiNotification[]> {
|
||||
return await this.#packManyInternal(notifications, meId);
|
||||
return await this.#packManyInternal(notifications, me);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async packGroupedMany(
|
||||
notifications: MiGroupedNotification[],
|
||||
meId: MiUser['id'],
|
||||
me: MiUser,
|
||||
): Promise<MiGroupedNotification[]> {
|
||||
return await this.#packManyInternal(notifications, meId);
|
||||
return await this.#packManyInternal(notifications, me);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -304,12 +302,12 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
notification: T,
|
||||
userIdsWhoMeMuting: Set<MiUser['id']>,
|
||||
userMutedInstances: Set<string>,
|
||||
notifiers: MiUser[],
|
||||
notifiers: Map<string, MiUser>,
|
||||
): boolean {
|
||||
if (!('notifierId' in notification)) return true;
|
||||
if (userIdsWhoMeMuting.has(notification.notifierId)) return false;
|
||||
|
||||
const notifier = notifiers.find(x => x.id === notification.notifierId) ?? null;
|
||||
const notifier = notifiers.get(notification.notifierId) ?? null;
|
||||
|
||||
if (notifier == null) return false;
|
||||
if (notifier.host && userMutedInstances.has(notifier.host)) return false;
|
||||
|
|
@ -336,19 +334,18 @@ export class NotificationEntityService implements OnModuleInit {
|
|||
notifications: T[],
|
||||
meId: MiUser['id'],
|
||||
): Promise<T[]> {
|
||||
const notifierIds = notifications.map(notification => 'notifierId' in notification ? notification.notifierId : null).filter(x => x != null);
|
||||
|
||||
const [
|
||||
userIdsWhoMeMuting,
|
||||
userMutedInstances,
|
||||
notifiers,
|
||||
] = await Promise.all([
|
||||
this.cacheService.userMutingsCache.fetch(meId),
|
||||
this.cacheService.userProfileCache.fetch(meId).then(p => new Set(p.mutedInstances)),
|
||||
this.cacheService.userMutingsCache.fetch(meId),
|
||||
this.cacheService.getUsers(notifierIds),
|
||||
]);
|
||||
|
||||
const notifierIds = notifications.map(notification => 'notifierId' in notification ? notification.notifierId : null).filter(x => x != null);
|
||||
const notifiers = notifierIds.length > 0 ? await this.usersRepository.find({
|
||||
where: { id: In(notifierIds) },
|
||||
}) : [];
|
||||
|
||||
const filteredNotifications = ((await Promise.all(notifications.map(async (notification) => {
|
||||
const isValid = this.#validateNotifier(notification, userIdsWhoMeMuting, userMutedInstances, notifiers);
|
||||
return isValid ? notification : null;
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
// this matches the logic in NotificationService and it's what MkPagination expects
|
||||
if (ps.sinceId && !ps.untilId) groupedNotifications.reverse();
|
||||
|
||||
return await this.notificationEntityService.packGroupedMany(groupedNotifications, me.id);
|
||||
return await this.notificationEntityService.packGroupedMany(groupedNotifications, me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
this.notificationService.readAllNotification(me.id);
|
||||
}
|
||||
|
||||
return await this.notificationEntityService.packMany(notifications, me.id);
|
||||
return await this.notificationEntityService.packMany(notifications, me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue