add redis cache to results
This commit is contained in:
@@ -16,9 +16,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
resultCachePrefix = "result:"
|
||||
resultCachePrefix = "result:"
|
||||
leaderboardCachePrefix = "leaderboard:"
|
||||
)
|
||||
|
||||
type leaderboardCache struct {
|
||||
Results []domain.Result `json:"results"`
|
||||
TotalCount int `json:"total_count"`
|
||||
}
|
||||
|
||||
type ResultRepository struct {
|
||||
db *sql.DB
|
||||
redisClient *redis.Client
|
||||
@@ -37,6 +43,21 @@ func (r *ResultRepository) cacheKey(id string) string {
|
||||
return resultCachePrefix + id
|
||||
}
|
||||
|
||||
func (r *ResultRepository) leaderboardCacheKey(competitionID uuid.UUID, limit, offset int) string {
|
||||
return fmt.Sprintf("%s%s:limit:%d:offset:%d", leaderboardCachePrefix, competitionID.String(), limit, offset)
|
||||
}
|
||||
|
||||
func (r *ResultRepository) invalidateLeaderboardCache(ctx context.Context, competitionID uuid.UUID) {
|
||||
if !r.cacheEnabled {
|
||||
return
|
||||
}
|
||||
pattern := fmt.Sprintf("%s%s:*", leaderboardCachePrefix, competitionID.String())
|
||||
keys, err := r.redisClient.Keys(ctx, pattern).Result()
|
||||
if err == nil && len(keys) > 0 {
|
||||
r.redisClient.Del(ctx, keys...).Err()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ResultRepository) Create(ctx context.Context, result *domain.Result) error {
|
||||
metadataJSON, err := json.Marshal(result.Metadata)
|
||||
if err != nil {
|
||||
@@ -65,6 +86,7 @@ func (r *ResultRepository) Create(ctx context.Context, result *domain.Result) er
|
||||
}
|
||||
|
||||
if r.cacheEnabled {
|
||||
r.invalidateLeaderboardCache(ctx, result.CompetitionID)
|
||||
data, err := json.Marshal(result)
|
||||
if err == nil {
|
||||
r.redisClient.Set(ctx, r.cacheKey(result.ID.String()), data, 10*time.Minute).Err()
|
||||
@@ -160,6 +182,7 @@ func (r *ResultRepository) Update(ctx context.Context, result *domain.Result) er
|
||||
}
|
||||
|
||||
if r.cacheEnabled {
|
||||
r.invalidateLeaderboardCache(ctx, result.CompetitionID)
|
||||
r.redisClient.Del(ctx, r.cacheKey(result.ID.String())).Err()
|
||||
}
|
||||
|
||||
@@ -312,6 +335,16 @@ func (r *ResultRepository) GetByCompetitionAndUser(ctx context.Context, competit
|
||||
}
|
||||
|
||||
func (r *ResultRepository) GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int, offset int) ([]domain.Result, int, error) {
|
||||
if r.cacheEnabled {
|
||||
key := r.leaderboardCacheKey(competitionID, limit, offset)
|
||||
val, err := r.redisClient.Get(ctx, key).Result()
|
||||
if err == nil {
|
||||
var cached leaderboardCache
|
||||
if json.Unmarshal([]byte(val), &cached) == nil {
|
||||
return cached.Results, cached.TotalCount, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
countQuery := `SELECT COUNT(*) FROM results WHERE competition_id = $1 AND status = $2`
|
||||
var total int
|
||||
if err := r.db.QueryRowContext(ctx, countQuery, competitionID, domain.ResultStatusCompleted).Scan(&total); err != nil {
|
||||
@@ -359,6 +392,15 @@ func (r *ResultRepository) GetLeaderboard(ctx context.Context, competitionID uui
|
||||
results = append(results, result)
|
||||
}
|
||||
|
||||
if r.cacheEnabled {
|
||||
key := r.leaderboardCacheKey(competitionID, limit, offset)
|
||||
cacheData := leaderboardCache{Results: results, TotalCount: total}
|
||||
data, err := json.Marshal(cacheData)
|
||||
if err == nil {
|
||||
r.redisClient.Set(ctx, key, data, 1*time.Minute).Err()
|
||||
}
|
||||
}
|
||||
|
||||
return results, total, nil
|
||||
}
|
||||
|
||||
@@ -382,7 +424,16 @@ func (r *ResultRepository) UpdateStatus(ctx context.Context, id uuid.UUID, statu
|
||||
r.redisClient.Del(ctx, r.cacheKey(id.String())).Err()
|
||||
}
|
||||
|
||||
return r.Get(ctx, id)
|
||||
result, err := r.Get(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.cacheEnabled {
|
||||
r.invalidateLeaderboardCache(ctx, result.CompetitionID)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *ResultRepository) RecalculateRanks(ctx context.Context, competitionID uuid.UUID) error {
|
||||
@@ -425,5 +476,14 @@ func (r *ResultRepository) RecalculateRanks(ctx context.Context, competitionID u
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.cacheEnabled {
|
||||
r.invalidateLeaderboardCache(ctx, competitionID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user