Skip to content

Commit

Permalink
perf: redis everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
ImSoZRious committed Mar 30, 2024
1 parent 1b3d50e commit 799153e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 7 deletions.
2 changes: 1 addition & 1 deletion apps/server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ FROM node:20.12.0-alpine3.19 AS runner

WORKDIR /app

COPY --from=builder /build/dist/ ./dist/
COPY package*.json ./
RUN npm install --omit=dev
COPY --from=builder /build/dist/ ./dist/

EXPOSE 3000

Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/controller/player.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class PlayerController {
this.playerService
.getScoreboard(
game.id,
game.game.actions.map((a) => a.key),
game.game.actions.map((a: any) => a.key),
)
.then((score) => {
socket.emit('scoreboard', score)
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/models/client.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DataTypes, Filterable, Model, WhereOptions } from 'sequelize'
import { ClientAttributes, ClientInput } from '$/interface/client.interface'
import { sequelizeConnection } from '$/utils/database'
import { RedisClientType, RedisDefaultModules, RedisFunctions, RedisScripts } from 'redis'

export class Client
extends Model<ClientAttributes, ClientInput>
Expand Down
28 changes: 28 additions & 0 deletions apps/server/src/models/game.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { DataTypes, Model, col, fn } from 'sequelize'
import { GameAttributes, GameInput } from '$/interface/game.interface'
import { sequelizeConnection } from '$/utils/database'
import { GameHistory } from './history.model'
import { RedisClientType, RedisDefaultModules, RedisFunctions, RedisScripts } from 'redis'
import { createLogger } from '$/utils/logger'

export class Game
extends Model<GameAttributes, GameInput>
Expand Down Expand Up @@ -57,7 +59,19 @@ Game.init(
{ timestamps: true, sequelize: sequelizeConnection, paranoid: true },
)

const LAST_ACTIVE_CACHE_KEY = "db::last_active"

export class GameRepository {
logger = createLogger('GameRepository')

constructor(
private readonly redis: RedisClientType<
RedisDefaultModules,
RedisFunctions,
RedisScripts
>,
) {}

async getAllGames(): Promise<Game[]> {
return Game.findAll()
}
Expand All @@ -67,6 +81,16 @@ export class GameRepository {
}

async getLastActiveGame() {
const cache = await this.redis.get(LAST_ACTIVE_CACHE_KEY)
if (cache) {
try {
const game = JSON.parse(cache)
return game
} catch (e) {
this.logger.warn(`last active cache is not JSON ${cache}`)
await this.redis.del(LAST_ACTIVE_CACHE_KEY)
}
}
const game = await Game.findOne({
order: [['updatedAt', 'DESC']],
attributes: ['id', 'open', 'actions'],
Expand All @@ -76,10 +100,12 @@ export class GameRepository {
game: res,
status: res?.open ? 'playing' : 'waiting',
}))
await this.redis.set(LAST_ACTIVE_CACHE_KEY, JSON.stringify(game))
return game
}

async createGame(game: Game) {
await this.redis.set(`game_key::${game.id}`, game.actions.map(x => x.key).join(','))
return Game.create(game)
}

Expand All @@ -96,6 +122,7 @@ export class GameRepository {
}

async startGame(game_id: string) {
await this.redis.del(LAST_ACTIVE_CACHE_KEY)
return Game.findOne({ where: { open: true } }).then(async (game) => {
await game?.update({ open: false })
return Game.update(
Expand All @@ -111,6 +138,7 @@ export class GameRepository {
}

async endGame(id: string) {
await this.redis.del(LAST_ACTIVE_CACHE_KEY)
return Game.update({ open: false }, { where: { id } }).then(() => {
const keys = Game.findOne({
where: { id },
Expand Down
24 changes: 20 additions & 4 deletions apps/server/src/models/history.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,33 @@ export class GameHistoryRepository {
key: string,
vote: number,
) {
const allKeys = await this.redis.get(`game_key::${game_id}`)
const total = await this.redis.incrBy(`game::${game_id}::${key}`, vote)
this.redis.keys(`game::${game_id}::*`).then(async (keys) => {
keys.forEach(async (k) => {
if (k !== `game::${game_id}::${key}`) {
if (!allKeys) {
this.redis.keys(`game::${game_id}::*`).then(async (keys) => {
const allKeys: string[] = []
keys.forEach(async (k) => {
const thisKey = k.split("::")[2]
allKeys.push(thisKey)
if (thisKey != key) {
const kTotal = parseInt((await this.redis.get(k)) || '0')
const decrease = Math.floor((Math.abs(total - kTotal) * vote) / 100)
const remain = kTotal - decrease
if (remain > 0) this.redis.decrBy(k, decrease)
}
})
await this.redis.set(`game_key::${game_id}`, allKeys.join(","))
})
} else {
allKeys.split(",").forEach(async k => {
if (k != key) {
const kTotal = parseInt((await this.redis.get(k)) || '0')
const decrease = Math.floor((Math.abs(total - kTotal) * vote) / 100)
const remain = kTotal - decrease
if (remain > 0) this.redis.decrBy(k, decrease)
}
})
})
}
}

async getHistoryByPlayerID(game_id: string, player_id: string) {
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function initServer(app: Express, server: HTTPServer) {
})
sequelizeConnection.sync({ force: process.env.FORCE_DB_SYNC === 'true' })

const gameRepository = new GameRepository()
const gameRepository = new GameRepository(pubClient)
const clientRepository = new ClientRepository()
const gameHistoryRepository = new GameHistoryRepository(pubClient)

Expand Down

0 comments on commit 799153e

Please sign in to comment.