mirror of
https://github.com/amineo/t2-stat-parser.git
synced 2026-01-19 17:34:43 +00:00
* Add query caching for lthe long running leaderboard queries -- 2hr ttl
This commit is contained in:
parent
4df3a1b594
commit
86e13db165
4684
app/api/package-lock.json
generated
4684
app/api/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -25,32 +25,34 @@
|
||||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/common": "^7.4.4",
|
"@nestjs/common": "^8.0.7",
|
||||||
"@nestjs/config": "^0.5.0",
|
"@nestjs/config": "^1.0.1",
|
||||||
"@nestjs/core": "^7.4.4",
|
"@nestjs/core": "^8.0.7",
|
||||||
"@nestjs/mapped-types": "^0.1.0",
|
"@nestjs/mapped-types": "^1.0.0",
|
||||||
"@nestjs/platform-express": "^7.4.4",
|
"@nestjs/platform-express": "^8.0.7",
|
||||||
"@nestjs/swagger": "^4.5.12",
|
"@nestjs/swagger": "^5.0.9",
|
||||||
"@nestjs/typeorm": "^7.1.4",
|
"@nestjs/typeorm": "^8.0.2",
|
||||||
|
"cache-manager": "^3.4.4",
|
||||||
"class-transformer": "^0.3.1",
|
"class-transformer": "^0.3.1",
|
||||||
"class-validator": "^0.12.2",
|
"class-validator": "^0.12.2",
|
||||||
"joi": "^17.2.1",
|
"joi": "^17.4.2",
|
||||||
"pg": "^8.3.2",
|
"pg": "^8.7.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^6.6.3",
|
"rxjs": "^7.3.0",
|
||||||
"swagger-ui-express": "^4.1.4",
|
"swagger-ui-express": "^4.1.6",
|
||||||
"typeorm": "^0.2.26"
|
"typeorm": "^0.2.37"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^7.0.0",
|
"@nestjs/cli": "^8.1.1",
|
||||||
"@nestjs/schematics": "^7.1.2",
|
"@nestjs/schematics": "^8.0.3",
|
||||||
"@nestjs/testing": "^7.4.4",
|
"@nestjs/testing": "^8.0.7",
|
||||||
"@types/express": "^4.17.8",
|
"@types/cache-manager": "^3.4.2",
|
||||||
"@types/hapi__joi": "^17.1.4",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "^26.0.14",
|
"@types/hapi__joi": "^17.1.7",
|
||||||
"@types/node": "^14.11.1",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/supertest": "^2.0.8",
|
"@types/node": "^16.10.1",
|
||||||
|
"@types/supertest": "^2.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^3.10.1",
|
"@typescript-eslint/eslint-plugin": "^3.10.1",
|
||||||
"@typescript-eslint/parser": "^3.10.1",
|
"@typescript-eslint/parser": "^3.10.1",
|
||||||
"eslint": "^7.9.0",
|
"eslint": "^7.9.0",
|
||||||
|
|
@ -63,7 +65,7 @@
|
||||||
"ts-loader": "^8.0.3",
|
"ts-loader": "^8.0.3",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^9.0.0",
|
||||||
"tsconfig-paths": "^3.9.0",
|
"tsconfig-paths": "^3.9.0",
|
||||||
"typescript": "^4.0.2"
|
"typescript": "^4.4.3"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Controller, Get, Query, Param } from '@nestjs/common';
|
import { Controller, Get, Query, Param, Inject, CACHE_MANAGER } from '@nestjs/common';
|
||||||
|
import { Cache } from 'cache-manager';
|
||||||
import { ApiOperation } from '@nestjs/swagger';
|
import { ApiOperation } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { PlayersService } from './players.service';
|
import { PlayersService } from './players.service';
|
||||||
|
|
@ -7,10 +8,14 @@ import {
|
||||||
TopAccuracyQueryDto,
|
TopAccuracyQueryDto,
|
||||||
TopWinsQueryDto,
|
TopWinsQueryDto,
|
||||||
} from '../common/dto/top-players-query.dto';
|
} from '../common/dto/top-players-query.dto';
|
||||||
|
import { cache } from 'joi';
|
||||||
|
|
||||||
@Controller('players')
|
@Controller('players')
|
||||||
export class PlayersController {
|
export class PlayersController {
|
||||||
constructor(private readonly playerService: PlayersService) {}
|
constructor(
|
||||||
|
private readonly playerService: PlayersService,
|
||||||
|
@Inject(CACHE_MANAGER) private cacheManager: Cache
|
||||||
|
) {}
|
||||||
|
|
||||||
// /players
|
// /players
|
||||||
@Get()
|
@Get()
|
||||||
|
|
@ -25,7 +30,7 @@ export class PlayersController {
|
||||||
tags: ['Player', 'Leaderboard'],
|
tags: ['Player', 'Leaderboard'],
|
||||||
summary: 'Return a leaderboard of players for a specific accuracy stat',
|
summary: 'Return a leaderboard of players for a specific accuracy stat',
|
||||||
})
|
})
|
||||||
findTopAccuracy(@Query() topPlayersQuery: TopAccuracyQueryDto) {
|
async findTopAccuracy(@Query() topPlayersQuery: TopAccuracyQueryDto) {
|
||||||
const {
|
const {
|
||||||
stat,
|
stat,
|
||||||
gameType,
|
gameType,
|
||||||
|
|
@ -34,27 +39,54 @@ export class PlayersController {
|
||||||
limit = 10,
|
limit = 10,
|
||||||
timePeriod,
|
timePeriod,
|
||||||
} = topPlayersQuery;
|
} = topPlayersQuery;
|
||||||
return this.playerService.findTopAccuracy({
|
|
||||||
stat,
|
const cacheKey =`topacc_${stat}_${gameType}_${minGames}_${minShots}_${limit}_${timePeriod}`;
|
||||||
gameType,
|
const queryCache = await this.cacheManager.get(cacheKey);
|
||||||
minGames,
|
|
||||||
minShots,
|
if(!queryCache){
|
||||||
limit,
|
const results = await this.playerService.findTopAccuracy({
|
||||||
timePeriod,
|
stat,
|
||||||
});
|
gameType,
|
||||||
|
minGames,
|
||||||
|
minShots,
|
||||||
|
limit,
|
||||||
|
timePeriod,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.cacheManager.set(cacheKey, results, { ttl: 3600 * 2 }); // 2 hours
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Get('top/wins')
|
@Get('top/wins')
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
tags: ['Player', 'Leaderboard'],
|
tags: ['Player', 'Leaderboard'],
|
||||||
summary: 'Return a leaderboard of players for win percentage',
|
summary: 'Return a leaderboard of players for win percentage',
|
||||||
})
|
})
|
||||||
findTopWins(@Query() topPlayersQuery: TopWinsQueryDto) {
|
async findTopWins(@Query() topPlayersQuery: TopWinsQueryDto) {
|
||||||
const { minGames = 100, limit = 10, timePeriod } = topPlayersQuery;
|
const { minGames = 100, limit = 10, timePeriod } = topPlayersQuery;
|
||||||
return this.playerService.findTopWins({
|
|
||||||
minGames,
|
const cacheKey =`topwins_${minGames}_${limit}_${timePeriod}`;
|
||||||
limit,
|
const queryCache = await this.cacheManager.get(cacheKey);
|
||||||
timePeriod,
|
|
||||||
});
|
/*
|
||||||
|
If we don't have a cache ready, lets make one so the next hit is super fast
|
||||||
|
Cache ttl is in seconds
|
||||||
|
*/
|
||||||
|
if(!queryCache){
|
||||||
|
const results = await this.playerService.findTopWins({
|
||||||
|
minGames,
|
||||||
|
limit,
|
||||||
|
timePeriod,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.cacheManager.set(cacheKey, results, { ttl: 3600 * 2 }); // 2 hours
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryCache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module, CacheModule } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
|
@ -9,7 +9,11 @@ import { Players } from './entities/Players';
|
||||||
import { GameDetail } from '../game/entities/GameDetail';
|
import { GameDetail } from '../game/entities/GameDetail';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Players, GameDetail]), ConfigModule],
|
imports: [
|
||||||
|
CacheModule.register(),
|
||||||
|
TypeOrmModule.forFeature([Players, GameDetail]),
|
||||||
|
ConfigModule
|
||||||
|
],
|
||||||
providers: [PlayersService],
|
providers: [PlayersService],
|
||||||
controllers: [PlayersController],
|
controllers: [PlayersController],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue