perf(backend): 通知をRedisに保存するように

Resolve #10168
This commit is contained in:
syuilo 2023-04-04 14:06:57 +09:00
parent 38d0b62167
commit 30d6992684
29 changed files with 185 additions and 613 deletions

View file

@ -1,5 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { In, Not } from 'typeorm';
import Redis from 'ioredis';
import Ajv from 'ajv';
import { ModuleRef } from '@nestjs/core';
import { DI } from '@/di-symbols.js';
@ -12,7 +13,7 @@ import { KVCache } from '@/misc/cache.js';
import type { Instance } from '@/models/entities/Instance.js';
import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js';
import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js';
import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, NotificationsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, AnnouncementsRepository, PagesRepository, UserProfile, RenoteMutingsRepository } from '@/models/index.js';
import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, AnnouncementsRepository, PagesRepository, UserProfile, RenoteMutingsRepository } from '@/models/index.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import type { OnModuleInit } from '@nestjs/common';
@ -60,6 +61,9 @@ export class UserEntityService implements OnModuleInit {
@Inject(DI.config)
private config: Config,
@Inject(DI.redis)
private redisClient: Redis.Redis,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@ -90,9 +94,6 @@ export class UserEntityService implements OnModuleInit {
@Inject(DI.channelFollowingsRepository)
private channelFollowingsRepository: ChannelFollowingsRepository,
@Inject(DI.notificationsRepository)
private notificationsRepository: NotificationsRepository,
@Inject(DI.userNotePiningsRepository)
private userNotePiningsRepository: UserNotePiningsRepository,
@ -247,21 +248,17 @@ export class UserEntityService implements OnModuleInit {
@bindThis
public async getHasUnreadNotification(userId: User['id']): Promise<boolean> {
const mute = await this.mutingsRepository.findBy({
muterId: userId,
});
const mutedUserIds = mute.map(m => m.muteeId);
const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`);
const latestNotificationIdsRes = await this.redisClient.xrevrange(
`notificationTimeline:${userId}`,
'+',
'-',
'COUNT', 1);
console.log('latestNotificationIdsRes', latestNotificationIdsRes);
const latestNotificationId = latestNotificationIdsRes[0]?.[0];
const count = await this.notificationsRepository.count({
where: {
notifieeId: userId,
...(mutedUserIds.length > 0 ? { notifierId: Not(In(mutedUserIds)) } : {}),
isRead: false,
},
take: 1,
});
return count > 0;
return latestNotificationId != null && (latestReadNotificationId == null || latestReadNotificationId < latestNotificationId);
}
@bindThis