diff --git a/server/app/Controllers/Http/SummonersController.ts b/server/app/Controllers/Http/SummonersController.ts index 25f2203..8530f79 100644 --- a/server/app/Controllers/Http/SummonersController.ts +++ b/server/app/Controllers/Http/SummonersController.ts @@ -33,7 +33,6 @@ export default class SummonersController { public async basic({ request, response }: HttpContextContract) { console.time('BASIC_REQUEST') const { summoner, region } = await request.validate(SummonerBasicValidator) - const finalJSON: any = {} try { const account = await SummonerService.getAccount(summoner, region) @@ -41,16 +40,20 @@ export default class SummonersController { if (!account) { return response.json(null) } - finalJSON.account = account // Summoner in DB const summonerDB = await Summoner.firstOrCreate({ puuid: account.puuid }) - // Summoner names - finalJSON.account.names = await SummonerService.getAllSummonerNames(account, summonerDB) - - // Only last 100 matchIds in matchlist - await MatchService.updateMatchList(account.puuid, region, MatchListMode.LIGHT) + const [names, seasons, gamemodes, current, ranked, recentActivity] = await Promise.all([ + await SummonerService.getAllSummonerNames(account, summonerDB), + this.getSeasons(account.puuid), + MatchRepository.gamemodes(account.puuid), + Jax.Spectator.summonerID(account.id, region), + SummonerService.getRanked(account.id, region), + MatchRepository.recentActivity(account.puuid), + // Only last 100 matchIds in matchlist + await MatchService.updateMatchList(account.puuid, region, MatchListMode.LIGHT), + ]) // Add job in 1sec to load entire matchlist in DB (in background) const matchListMode = summonerDB.$isLocal ? MatchListMode.FIRSTIME : MatchListMode.UPDATE @@ -60,33 +63,23 @@ export default class SummonersController { 1000 ) - // All seasons the summoner has played - finalJSON.seasons = await this.getSeasons(account.puuid) - - // All gamemodes the summoner has played - finalJSON.gamemodes = (await MatchRepository.gamemodes(account.puuid)).map((g) => g.gamemode) - - // CURRENT GAME - console.time('playing') - finalJSON.current = await Jax.Spectator.summonerID(account.id, region) - finalJSON.playing = !!finalJSON.current - console.timeEnd('playing') - - // RANKED STATS - console.time('ranked') - finalJSON.ranked = await SummonerService.getRanked(account.id, region) - console.timeEnd('ranked') - - // RECENT ACTIVITY - finalJSON.recentActivity = await StatsService.getRecentActivity(account.puuid) + console.timeEnd('BASIC_REQUEST') + return response.json({ + account: { + ...account, + names, + }, + seasons, // All seasons the summoner has played + gamemodes: gamemodes.map((g) => g.gamemode), // All gamemodes the summoner has played + playing: !!current, + ranked, + recentActivity, + }) } catch (e) { console.log(e) console.timeEnd('BASIC_REQUEST') return response.json(null) } - - console.timeEnd('BASIC_REQUEST') - return response.json(finalJSON) } /** diff --git a/server/app/Repositories/MatchRepository.ts b/server/app/Repositories/MatchRepository.ts index 18d22aa..2a12fc7 100644 --- a/server/app/Repositories/MatchRepository.ts +++ b/server/app/Repositories/MatchRepository.ts @@ -82,6 +82,7 @@ class MatchRepository { } public async recentActivity(puuid: string) { + console.time('RECENT_ACTIVITY') const query = ` SELECT to_timestamp(matches.date/1000)::date as day, @@ -100,10 +101,12 @@ class MatchRepository { day ` const { rows } = await Database.rawQuery(query, { puuid }) + console.timeEnd('RECENT_ACTIVITY') return rows } public async globalStats(filters: SelectFilters) { + console.time('GLOBAL') const query = ` SELECT COALESCE(SUM(match_players.kills), 0) as kills, @@ -126,10 +129,12 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('GLOBAL') return rows[0] } public async gamemodeStats(filters: SelectFilters) { + console.time('GAMEMODE') const query = ` SELECT matches.gamemode as id, @@ -148,10 +153,12 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('GAMEMODE') return rows } public async roleStats(filters: SelectFilters) { + console.time('ROLE') const query = ` SELECT match_players.team_position as role, @@ -169,10 +176,12 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('ROLE') return rows } public async championStats(filters: SelectFilters) { + console.time('CHAMPION') const query = ` SELECT match_players.champion_id as id, @@ -196,10 +205,12 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('CHAMPION') return rows } public async championClassStats(filters: SelectFilters) { + console.time('CHAMPION-CLASS') const query = ` SELECT match_players.champion_role as id, @@ -218,10 +229,12 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('CHAMPION-CLASS') return rows } public async mates(filters: SelectFilters) { + console.time('MATES') const query = ` SELECT ( @@ -255,6 +268,7 @@ class MatchRepository { ` const { rows } = await Database.rawQuery(query, filters as any) + console.timeEnd('MATES') // Remove the Summoner himself + unique game mates return rows.splice(1).filter((row) => row.count > 1) diff --git a/server/app/Services/StatsService.ts b/server/app/Services/StatsService.ts index 53b4bf9..738f5a5 100644 --- a/server/app/Services/StatsService.ts +++ b/server/app/Services/StatsService.ts @@ -4,24 +4,28 @@ import MatchRepository, { SelectFilters } from 'App/Repositories/MatchRepository import BasicMatchSerializer from 'App/Serializers/BasicMatchSerializer' class StatsService { - public async getRecentActivity(puuid: string) { - console.time('RecentActivity') - const recentActivity = await MatchRepository.recentActivity(puuid) - console.timeEnd('RecentActivity') - return recentActivity - } public async getSummonerStats(puuid: string, season?: number) { const filters: SelectFilters = { puuid } if (season) filters.season = season - console.time('GLOBAL') - const globalStats = await MatchRepository.globalStats(filters) - console.timeEnd('GLOBAL') - console.time('GAMEMODE') - const gamemodeStats = await MatchRepository.gamemodeStats(filters) - console.timeEnd('GAMEMODE') - console.time('ROLE') - const roleStats = await MatchRepository.roleStats(filters) + const [ + globalStats, + gamemodeStats, + roleStats, + championStats, + championClassStats, + mates, + recentActivity, + ] = await Promise.all([ + MatchRepository.globalStats(filters), + MatchRepository.gamemodeStats(filters), + MatchRepository.roleStats(filters), + MatchRepository.championStats({ ...filters, limit: 5 }), + MatchRepository.championClassStats(filters), + MatchRepository.mates(filters), + MatchRepository.recentActivity(puuid), + ]) + // Check if all roles are in the array const roles = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'UTILITY'] for (const role of roles) { @@ -37,26 +41,12 @@ class StatsService { }) } } - console.timeEnd('ROLE') - console.time('CHAMPION') - const championStats = await MatchRepository.championStats({ ...filters, limit: 5 }) for (const champ of championStats) { champ.champion = BasicMatchSerializer.getChampion(champ.id) } - console.timeEnd('CHAMPION') - console.time('CHAMPION-CLASS') - const championClassStats = await MatchRepository.championClassStats(filters) for (const champ of championClassStats) { champ.id = ChampionRoles[champ.id] } - console.timeEnd('CHAMPION-CLASS') - console.time('MATES') - const mates = await MatchRepository.mates(filters) - console.timeEnd('MATES') - - console.time('RECENT_ACTIVITY') - const recentActivity = await MatchRepository.recentActivity(puuid) - console.timeEnd('RECENT_ACTIVITY') return { global: globalStats,