File tree Expand file tree Collapse file tree 4 files changed +16
-6
lines changed
Expand file tree Collapse file tree 4 files changed +16
-6
lines changed Original file line number Diff line number Diff line change 99 " Bash(ls:*)" ,
1010 " Bash(git push:*)" ,
1111 " Bash(grep:*)" ,
12- " Bash(mkdir:*)"
12+ " Bash(mkdir:*)" ,
13+ " Bash(npm run build:*)"
1314 ],
1415 "deny" : []
1516 }
Original file line number Diff line number Diff line change 11import User from '../models/User.js' ;
22import UserStats from '../models/UserStats.js' ;
33
4- // Improved caching with separate keys for different modes
5- const CACHE_DURATION = 60000 ; // 1 minute cache
4+ // Production-scale caching for 2M+ users
5+ const CACHE_DURATION = 300000 ; // 5 minute cache for production performance
6+ const DAILY_CACHE_DURATION = 180000 ; // 3 minute cache for daily leaderboards (more frequent updates)
67const cache = new Map ( ) ;
78
89function getCacheKey ( mode , pastDay ) {
@@ -11,7 +12,8 @@ function getCacheKey(mode, pastDay) {
1112
1213function getCachedData ( key ) {
1314 const cached = cache . get ( key ) ;
14- if ( cached && Date . now ( ) - cached . timestamp < CACHE_DURATION ) {
15+ const cacheDuration = key . includes ( 'daily' ) ? DAILY_CACHE_DURATION : CACHE_DURATION ;
16+ if ( cached && Date . now ( ) - cached . timestamp < cacheDuration ) {
1517 return cached . data ;
1618 }
1719 return null ;
Original file line number Diff line number Diff line change @@ -794,7 +794,7 @@ singlePlayerRound={singlePlayerRound} onboarding={onboarding} countryGuesser={co
794794 } } panoShown = { showPanoOnResult } />
795795
796796 { /* Critical timer screen warning effect */ }
797- { ( ( timeToNextMultiplayerEvt <= 5 && timeToNextMultiplayerEvt > 0 && multiplayerTimerShown && ! showAnswer && ! pinPoint && multiplayerState ?. inGame && multiplayerState ?. gameData ?. state === 'guess' ) ||
797+ { ( ( timeToNextMultiplayerEvt <= 5 && timeToNextMultiplayerEvt > 0 && multiplayerTimerShown && ! showAnswer && ! pinPoint && multiplayerState ?. inGame && multiplayerState ?. gameData ?. state === 'guess' ) ||
798798 ( timeToNextRound <= 5 && timeToNextRound > 0 && onboardingTimerShown && ! showAnswer && ! pinPoint && onboarding ) ) && (
799799 < div className = "screen-critical-warning" />
800800 ) }
Original file line number Diff line number Diff line change @@ -60,12 +60,19 @@ const userStatsSchema = new mongoose.Schema({
6060 }
6161} ) ;
6262
63- // Compound indexes for efficient querying
63+ // Production-grade indexes for 2M+ users with 20k daily active
6464userStatsSchema . index ( { userId : 1 , timestamp : - 1 } ) ; // User's stats over time (descending)
6565userStatsSchema . index ( { userId : 1 , timestamp : 1 } ) ; // User's stats over time (ascending)
6666userStatsSchema . index ( { timestamp : - 1 , xpRank : 1 } ) ; // Leaderboard snapshots by XP
6767userStatsSchema . index ( { timestamp : - 1 , eloRank : 1 } ) ; // Leaderboard snapshots by ELO
6868
69+ // CRITICAL: Production performance indexes for daily leaderboards
70+ userStatsSchema . index ( { timestamp : - 1 , userId : 1 } ) ; // Efficient timestamp range + userId lookup
71+ userStatsSchema . index ( { timestamp : - 1 , totalXp : - 1 } ) ; // Fast XP leaderboard by time
72+ userStatsSchema . index ( { timestamp : - 1 , elo : - 1 } ) ; // Fast ELO leaderboard by time
73+ userStatsSchema . index ( { timestamp : - 1 , userId : 1 , totalXp : - 1 } ) ; // Compound for XP daily queries
74+ userStatsSchema . index ( { timestamp : - 1 , userId : 1 , elo : - 1 } ) ; // Compound for ELO daily queries
75+
6976// Static methods for common queries
7077userStatsSchema . statics = {
7178
You can’t perform that action at this time.
0 commit comments