diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-04-03 11:49:58 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-04-03 11:49:58 +0900 |
| commit | 4f9f625e6574990dfcd736c7a7d059af8fef7234 (patch) | |
| tree | e19f60108463e9a82084a3e20599ba51e48071f0 /packages/backend/src/server/api | |
| parent | enhance(server): 動画サムネイルの縦の長さを最大422pxにする (diff) | |
| download | sharkey-4f9f625e6574990dfcd736c7a7d059af8fef7234.tar.gz sharkey-4f9f625e6574990dfcd736c7a7d059af8fef7234.tar.bz2 sharkey-4f9f625e6574990dfcd736c7a7d059af8fef7234.zip | |
perf(backend): cache timeline of a channel to redis
Diffstat (limited to 'packages/backend/src/server/api')
| -rw-r--r-- | packages/backend/src/server/api/endpoints/channels/timeline.ts | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index cdaa400137..eef343d139 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -1,10 +1,12 @@ 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 { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import { DI } from '@/di-symbols.js'; +import { IdService } from '@/core/IdService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -48,12 +50,16 @@ export const paramDef = { @Injectable() export default class extends Endpoint<typeof meta, typeof paramDef> { constructor( + @Inject(DI.redis) + private redisClient: Redis.Redis, + @Inject(DI.notesRepository) private notesRepository: NotesRepository, @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, + private idService: IdService, private noteEntityService: NoteEntityService, private queryService: QueryService, private activeUsersChart: ActiveUsersChart, @@ -67,9 +73,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { throw new ApiError(meta.errors.noSuchChannel); } + const noteIdsRes = await this.redisClient.xrevrange( + `channelTimeline:${channel.id}`, + ps.untilId ? this.idService.parse(ps.untilId).date.getTime() : '+', + '-', + 'COUNT', ps.limit + 1); // untilIdに指定したものも含まれるため+1 + + if (noteIdsRes.length === 0) { + return []; + } + + const noteIds = noteIdsRes.map(x => x[1][1]).filter(x => x !== ps.untilId); + + if (noteIds.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 }) + const query = this.notesRepository.createQueryBuilder('note') + .where('note.id IN (:...noteIds)', { noteIds: noteIds }) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('user.avatar', 'avatar') .leftJoinAndSelect('user.banner', 'banner') @@ -90,7 +112,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { } //#endregion - const timeline = await query.take(ps.limit).getMany(); + const timeline = await query.getMany(); + timeline.sort((a, b) => a.id > b.id ? -1 : 1); if (me) this.activeUsersChart.read(me); |