diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2024-01-22 15:41:29 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2024-01-22 15:41:29 +0900 |
| commit | 94e282b612ad3dc6fd336a82fff19b290e11d221 (patch) | |
| tree | 2228600fea7aa80ad61cc03c762f17eb02fcd10a /packages/backend/src/core | |
| parent | enhance(reversi): some tweaks (diff) | |
| download | misskey-94e282b612ad3dc6fd336a82fff19b290e11d221.tar.gz misskey-94e282b612ad3dc6fd336a82fff19b290e11d221.tar.bz2 misskey-94e282b612ad3dc6fd336a82fff19b290e11d221.zip | |
perf(reversi): improve performance of reversi backend
Diffstat (limited to 'packages/backend/src/core')
| -rw-r--r-- | packages/backend/src/core/ReversiService.ts | 37 | ||||
| -rw-r--r-- | packages/backend/src/core/entities/ReversiGameEntityService.ts | 35 |
2 files changed, 52 insertions, 20 deletions
diff --git a/packages/backend/src/core/ReversiService.ts b/packages/backend/src/core/ReversiService.ts index 0e59d0308d..0d5f989c11 100644 --- a/packages/backend/src/core/ReversiService.ts +++ b/packages/backend/src/core/ReversiService.ts @@ -234,10 +234,13 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { map: Reversi.maps.eighteight.data, bw: 'random', isLlotheo: false, - }).then(x => this.reversiGamesRepository.findOneByOrFail(x.identifiers[0])); + }).then(x => this.reversiGamesRepository.findOneOrFail({ + where: { id: x.identifiers[0].id }, + relations: ['user1', 'user2'], + })); this.cacheGame(game); - const packed = await this.reversiGameEntityService.packDetail(game, { id: parentId }); + const packed = await this.reversiGameEntityService.packDetail(game); this.globalEventService.publishReversiStream(parentId, 'matched', { game: packed }); return game; @@ -267,6 +270,9 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { .returning('*') .execute() .then((response) => response.raw[0]); + // キャッシュ効率化のためにユーザー情報は再利用 + updatedGame.user1 = game.user1; + updatedGame.user2 = game.user2; this.cacheGame(updatedGame); //#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理 @@ -314,6 +320,9 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { .returning('*') .execute() .then((response) => response.raw[0]); + // キャッシュ効率化のためにユーザー情報は再利用 + updatedGame.user1 = game.user1; + updatedGame.user2 = game.user2; this.cacheGame(updatedGame); this.globalEventService.publishReversiGameStream(game.id, 'ended', { @@ -483,14 +492,36 @@ export class ReversiService implements OnApplicationShutdown, OnModuleInit { public async get(id: MiReversiGame['id']): Promise<MiReversiGame | null> { const cached = await this.redisClient.get(`reversi:game:cache:${id}`); if (cached != null) { + // TODO: この辺りのデシリアライズ処理をどこか別のサービスに切り出したい const parsed = JSON.parse(cached) as Serialized<MiReversiGame>; return { ...parsed, startedAt: parsed.startedAt != null ? new Date(parsed.startedAt) : null, endedAt: parsed.endedAt != null ? new Date(parsed.endedAt) : null, + user1: parsed.user1 != null ? { + ...parsed.user1, + avatar: null, + banner: null, + updatedAt: parsed.user1.updatedAt != null ? new Date(parsed.user1.updatedAt) : null, + lastActiveDate: parsed.user1.lastActiveDate != null ? new Date(parsed.user1.lastActiveDate) : null, + lastFetchedAt: parsed.user1.lastFetchedAt != null ? new Date(parsed.user1.lastFetchedAt) : null, + movedAt: parsed.user1.movedAt != null ? new Date(parsed.user1.movedAt) : null, + } : null, + user2: parsed.user2 != null ? { + ...parsed.user2, + avatar: null, + banner: null, + updatedAt: parsed.user2.updatedAt != null ? new Date(parsed.user2.updatedAt) : null, + lastActiveDate: parsed.user2.lastActiveDate != null ? new Date(parsed.user2.lastActiveDate) : null, + lastFetchedAt: parsed.user2.lastFetchedAt != null ? new Date(parsed.user2.lastFetchedAt) : null, + movedAt: parsed.user2.movedAt != null ? new Date(parsed.user2.movedAt) : null, + } : null, }; } else { - const game = await this.reversiGamesRepository.findOneBy({ id }); + const game = await this.reversiGamesRepository.findOne({ + where: { id }, + relations: ['user1', 'user2'], + }); if (game == null) return null; this.cacheGame(game); diff --git a/packages/backend/src/core/entities/ReversiGameEntityService.ts b/packages/backend/src/core/entities/ReversiGameEntityService.ts index bcb0fd5a6f..6c89a70599 100644 --- a/packages/backend/src/core/entities/ReversiGameEntityService.ts +++ b/packages/backend/src/core/entities/ReversiGameEntityService.ts @@ -9,7 +9,6 @@ import type { ReversiGamesRepository } from '@/models/_.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/Blocking.js'; -import type { MiUser } from '@/models/User.js'; import type { MiReversiGame } from '@/models/ReversiGame.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; @@ -29,10 +28,14 @@ export class ReversiGameEntityService { @bindThis public async packDetail( src: MiReversiGame['id'] | MiReversiGame, - me?: { id: MiUser['id'] } | null | undefined, ): Promise<Packed<'ReversiGameDetailed'>> { const game = typeof src === 'object' ? src : await this.reversiGamesRepository.findOneByOrFail({ id: src }); + const users = await Promise.all([ + this.userEntityService.pack(game.user1 ?? game.user1Id), + this.userEntityService.pack(game.user2 ?? game.user2Id), + ]); + return await awaitAll({ id: game.id, createdAt: this.idService.parse(game.id).date.toISOString(), @@ -46,10 +49,10 @@ export class ReversiGameEntityService { user2Ready: game.user2Ready, user1Id: game.user1Id, user2Id: game.user2Id, - user1: this.userEntityService.pack(game.user1Id, me), - user2: this.userEntityService.pack(game.user2Id, me), + user1: users[0], + user2: users[1], winnerId: game.winnerId, - winner: game.winnerId ? this.userEntityService.pack(game.winnerId, me) : null, + winner: game.winnerId ? users.find(u => u.id === game.winnerId)! : null, surrenderedUserId: game.surrenderedUserId, timeoutUserId: game.timeoutUserId, black: game.black, @@ -66,18 +69,21 @@ export class ReversiGameEntityService { @bindThis public packDetailMany( xs: MiReversiGame[], - me?: { id: MiUser['id'] } | null | undefined, ) { - return Promise.all(xs.map(x => this.packDetail(x, me))); + return Promise.all(xs.map(x => this.packDetail(x))); } @bindThis public async packLite( src: MiReversiGame['id'] | MiReversiGame, - me?: { id: MiUser['id'] } | null | undefined, ): Promise<Packed<'ReversiGameLite'>> { const game = typeof src === 'object' ? src : await this.reversiGamesRepository.findOneByOrFail({ id: src }); + const users = await Promise.all([ + this.userEntityService.pack(game.user1 ?? game.user1Id), + this.userEntityService.pack(game.user2 ?? game.user2Id), + ]); + return await awaitAll({ id: game.id, createdAt: this.idService.parse(game.id).date.toISOString(), @@ -85,16 +91,12 @@ export class ReversiGameEntityService { endedAt: game.endedAt && game.endedAt.toISOString(), isStarted: game.isStarted, isEnded: game.isEnded, - form1: game.form1, - form2: game.form2, - user1Ready: game.user1Ready, - user2Ready: game.user2Ready, user1Id: game.user1Id, user2Id: game.user2Id, - user1: this.userEntityService.pack(game.user1Id, me), - user2: this.userEntityService.pack(game.user2Id, me), + user1: users[0], + user2: users[1], winnerId: game.winnerId, - winner: game.winnerId ? this.userEntityService.pack(game.winnerId, me) : null, + winner: game.winnerId ? users.find(u => u.id === game.winnerId)! : null, surrenderedUserId: game.surrenderedUserId, timeoutUserId: game.timeoutUserId, black: game.black, @@ -109,9 +111,8 @@ export class ReversiGameEntityService { @bindThis public packLiteMany( xs: MiReversiGame[], - me?: { id: MiUser['id'] } | null | undefined, ) { - return Promise.all(xs.map(x => this.packLite(x, me))); + return Promise.all(xs.map(x => this.packLite(x))); } } |