diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b089aacd91dfb06b8144a14ed25a5c046758a59..623042488ca1614a734eed1f16e840609be3a1b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr - Ensure group count does not update when failing to add a member. - Handle Google IAP validation token caching when using credential overrides. - More graceful handling of no-op authoritative storage delete operations. +- Ensure rank cache is correctly updated when joining tournaments. ## [3.14.0] - 2022-10-14 ### Added diff --git a/server/api_tournament.go b/server/api_tournament.go index 60c6ddb23478243a039044e1bbba8b2045b9c356..19b0f65d854f79b2ac838b552119c7f941de5e61 100644 --- a/server/api_tournament.go +++ b/server/api_tournament.go @@ -61,7 +61,7 @@ func (s *ApiServer) JoinTournament(ctx context.Context, in *api.JoinTournamentRe tournamentID := in.GetTournamentId() - if err := TournamentJoin(ctx, s.logger, s.db, s.leaderboardCache, userID.String(), username, tournamentID); err != nil { + if err := TournamentJoin(ctx, s.logger, s.db, s.leaderboardCache, s.leaderboardRankCache, userID, username, tournamentID); err != nil { if err == runtime.ErrTournamentNotFound { return nil, status.Error(codes.NotFound, "Tournament not found.") } else if err == runtime.ErrTournamentMaxSizeReached { diff --git a/server/core_tournament.go b/server/core_tournament.go index 5f39beb17ae5be6cd4f2b003b5f3933630811bbd..67fed4ce305f3872709b30285a41fae979f023dc 100644 --- a/server/core_tournament.go +++ b/server/core_tournament.go @@ -107,7 +107,7 @@ func TournamentAddAttempt(ctx context.Context, logger *zap.Logger, db *sql.DB, c return nil } -func TournamentJoin(ctx context.Context, logger *zap.Logger, db *sql.DB, cache LeaderboardCache, owner, username, tournamentId string) error { +func TournamentJoin(ctx context.Context, logger *zap.Logger, db *sql.DB, cache LeaderboardCache, rankCache LeaderboardRankCache, ownerID uuid.UUID, username, tournamentId string) error { leaderboard := cache.Get(tournamentId) if leaderboard == nil { // If it does not exist treat it as success. @@ -136,13 +136,14 @@ func TournamentJoin(ctx context.Context, logger *zap.Logger, db *sql.DB, cache L return err } + var isNewJoin bool if err = ExecuteInTx(ctx, tx, func() error { query := `INSERT INTO leaderboard_record (leaderboard_id, owner_id, expiry_time, username, num_score, max_num_score) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT(owner_id, leaderboard_id, expiry_time) DO NOTHING` - result, err := tx.ExecContext(ctx, query, tournamentId, owner, time.Unix(expiryTime, 0).UTC(), username, 0, leaderboard.MaxNumScore) + result, err := tx.ExecContext(ctx, query, tournamentId, ownerID.String(), time.Unix(expiryTime, 0).UTC(), username, 0, leaderboard.MaxNumScore) if err != nil { return err } @@ -169,17 +170,24 @@ ON CONFLICT(owner_id, leaderboard_id, expiry_time) DO NOTHING` } } + isNewJoin = true + return nil }); err != nil { if err == runtime.ErrTournamentMaxSizeReached { - logger.Info("Failed to join tournament, reached max size allowed.", zap.String("tournament_id", tournamentId), zap.String("owner", owner), zap.String("username", username)) + logger.Info("Failed to join tournament, reached max size allowed.", zap.String("tournament_id", tournamentId), zap.String("owner", ownerID.String()), zap.String("username", username)) return err } logger.Error("Could not join tournament.", zap.Error(err)) return err } - logger.Info("Joined tournament.", zap.String("tournament_id", tournamentId), zap.String("owner", owner), zap.String("username", username)) + // Ensure new tournament joiner is included in the rank cache. + if isNewJoin { + _ = rankCache.Insert(leaderboard.Id, expiryTime, leaderboard.SortOrder, ownerID, 0, 0) + } + + logger.Info("Joined tournament.", zap.String("tournament_id", tournamentId), zap.String("owner", ownerID.String()), zap.String("username", username)) return nil } diff --git a/server/runtime_go_nakama.go b/server/runtime_go_nakama.go index 61c76ac37e8b72f28546cf5b509cff38315fdbce..bc72db2d8a3ab88016ea1b957faf8f0a712dc6c5 100644 --- a/server/runtime_go_nakama.go +++ b/server/runtime_go_nakama.go @@ -2567,7 +2567,9 @@ func (n *RuntimeGoNakamaModule) TournamentJoin(ctx context.Context, id, ownerID, if ownerID == "" { return errors.New("expects a owner ID string") - } else if _, err := uuid.FromString(ownerID); err != nil { + } + oid, err := uuid.FromString(ownerID) + if err != nil { return errors.New("expects owner ID to be a valid identifier") } @@ -2575,7 +2577,7 @@ func (n *RuntimeGoNakamaModule) TournamentJoin(ctx context.Context, id, ownerID, return errors.New("expects a username string") } - return TournamentJoin(ctx, n.logger, n.db, n.leaderboardCache, ownerID, username, id) + return TournamentJoin(ctx, n.logger, n.db, n.leaderboardCache, n.leaderboardRankCache, oid, username, id) } // @group tournaments diff --git a/server/runtime_javascript_nakama.go b/server/runtime_javascript_nakama.go index 602eaa22ebc9bd675f16f42440ab778a5095285c..836f264b1521b676ca0b790abc9e21429cc0b6f4 100644 --- a/server/runtime_javascript_nakama.go +++ b/server/runtime_javascript_nakama.go @@ -5956,7 +5956,9 @@ func (n *runtimeJavascriptNakamaModule) tournamentJoin(r *goja.Runtime) func(goj userID := getJsString(r, f.Argument(1)) if userID == "" { panic(r.NewTypeError("expects a user ID string")) - } else if _, err := uuid.FromString(userID); err != nil { + } + uid, err := uuid.FromString(userID) + if err != nil { panic(r.NewTypeError("expects user ID to be a valid identifier")) } @@ -5965,7 +5967,7 @@ func (n *runtimeJavascriptNakamaModule) tournamentJoin(r *goja.Runtime) func(goj panic(r.NewTypeError("expects a username string")) } - if err := TournamentJoin(n.ctx, n.logger, n.db, n.leaderboardCache, userID, username, id); err != nil { + if err := TournamentJoin(n.ctx, n.logger, n.db, n.leaderboardCache, n.rankCache, uid, username, id); err != nil { panic(r.NewGoError(fmt.Errorf("error joining tournament: %v", err.Error()))) } diff --git a/server/runtime_lua_nakama.go b/server/runtime_lua_nakama.go index e06ff72c9b918e33636ee47f098a402f5f01428d..c9c1787e5e8c4e4047371b61d7b7be1fc84f1ab3 100644 --- a/server/runtime_lua_nakama.go +++ b/server/runtime_lua_nakama.go @@ -7417,7 +7417,9 @@ func (n *RuntimeLuaNakamaModule) tournamentJoin(l *lua.LState) int { if userID == "" { l.ArgError(2, "expects a user ID string") return 0 - } else if _, err := uuid.FromString(userID); err != nil { + } + uid, err := uuid.FromString(userID) + if err != nil { l.ArgError(2, "expects user ID to be a valid identifier") return 0 } @@ -7428,7 +7430,7 @@ func (n *RuntimeLuaNakamaModule) tournamentJoin(l *lua.LState) int { return 0 } - if err := TournamentJoin(l.Context(), n.logger, n.db, n.leaderboardCache, userID, username, id); err != nil { + if err := TournamentJoin(l.Context(), n.logger, n.db, n.leaderboardCache, n.rankCache, uid, username, id); err != nil { l.RaiseError("error joining tournament: %v", err.Error()) } return 0