From fa67fb42b1baf616d860c54f6cdf9123fc7ed57a Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 8 Apr 2023 13:12:49 +0900 Subject: [PATCH] =?UTF-8?q?enhance(backend):=20Redis=E3=81=AB=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=83=B3=E3=83=8D=E3=83=AB=E6=8A=95=E7=A8=BF=E3=81=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E5=A0=B4=E5=90=88=E3=81=AFDB=E3=81=8B?= =?UTF-8?q?=E3=82=89=E6=8C=81=E3=81=A3=E3=81=A6=E3=81=8F=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #10473 --- .../server/api/endpoints/channels/timeline.ts | 75 ++++++++++++------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index dfc2a582dc..2556557b24 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import Redis from 'ioredis'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { ChannelsRepository, NotesRepository } from '@/models/index.js'; +import type { ChannelsRepository, Note, NotesRepository } from '@/models/index.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; @@ -73,6 +73,8 @@ export default class extends Endpoint { throw new ApiError(meta.errors.noSuchChannel); } + let timeline: Note[] = []; + const noteIdsRes = await this.redisClient.xrevrange( `channelTimeline:${channel.id}`, ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+', @@ -80,35 +82,52 @@ export default class extends Endpoint { 'COUNT', ps.limit + 1); // untilIdに指定したものも含まれるため+1 if (noteIdsRes.length === 0) { - return []; + //#region Construct query + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .andWhere('note.channelId = :channelId', { channelId: channel.id }) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('note.channel', 'channel'); + + if (me) { + this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateMutedNoteQuery(query, me); + this.queryService.generateBlockedUserQuery(query, me); + } + //#endregion + + timeline = await query.take(ps.limit).getMany(); + } else { + const noteIds = noteIdsRes.map(x => x[1][1]).filter(x => x !== ps.untilId); + + if (noteIds.length === 0) { + return []; + } + + //#region Construct query + const query = this.notesRepository.createQueryBuilder('note') + .where('note.id IN (:...noteIds)', { noteIds: noteIds }) + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('note.channel', 'channel'); + + if (me) { + this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateMutedNoteQuery(query, me); + this.queryService.generateBlockedUserQuery(query, me); + } + //#endregion + + timeline = await query.getMany(); + timeline.sort((a, b) => a.id > b.id ? -1 : 1); } - const noteIds = noteIdsRes.map(x => x[1][1]).filter(x => x !== ps.untilId); - - if (noteIds.length === 0) { - return []; - } - - //#region Construct query - const query = this.notesRepository.createQueryBuilder('note') - .where('note.id IN (:...noteIds)', { noteIds: noteIds }) - .innerJoinAndSelect('note.user', 'user') - .leftJoinAndSelect('note.reply', 'reply') - .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser') - .leftJoinAndSelect('note.channel', 'channel'); - - if (me) { - this.queryService.generateMutedUserQuery(query, me); - this.queryService.generateMutedNoteQuery(query, me); - this.queryService.generateBlockedUserQuery(query, me); - } - //#endregion - - const timeline = await query.getMany(); - timeline.sort((a, b) => a.id > b.id ? -1 : 1); - if (me) this.activeUsersChart.read(me); return await this.noteEntityService.packMany(timeline, me);