removed locks, switching to WAL for SQLite default

This commit is contained in:
2021-10-25 02:12:12 +02:00
parent c30da099ed
commit efd0f9a6af
6 changed files with 46 additions and 143 deletions

78
main.go
View File

@@ -29,7 +29,6 @@ import (
"os"
"os/signal"
"strconv"
"sync"
"syscall"
"time"
)
@@ -38,7 +37,7 @@ var (
conf = utils.Conf{}
demoLoader = &csgo.DemoMatchLoader{}
router *mux.Router
db *utils.DBWithLock
db *ent.Client
rdb *redis.Client
rdc *cache.Cache
firstHK = true
@@ -57,11 +56,9 @@ func housekeeping() {
firstHK = false
// update players from steam
db.Lock.RLock()
tPlayerNeedSteamUpdate, err := db.Client.Player.Query().Where(
tPlayerNeedSteamUpdate, err := db.Player.Query().Where(
player.SteamUpdatedLTE(time.Now().UTC().AddDate(0, 0, -1)),
).All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Errorf("[HK] Can't query players: %v", err)
continue
@@ -69,7 +66,7 @@ func housekeeping() {
if len(tPlayerNeedSteamUpdate) > 0 {
log.Infof("[HK] Refreshing %d profiles from steam", len(tPlayerNeedSteamUpdate))
_, err = utils.UpdatePlayerFromSteam(tPlayerNeedSteamUpdate, db.Client, conf.Steam.APIKey, db.Lock, rL)
_, err = utils.UpdatePlayerFromSteam(tPlayerNeedSteamUpdate, db, conf.Steam.APIKey, rL)
if err != nil {
log.Warningf("[HK] Unable to update profiles from steam: %v", err)
}
@@ -81,8 +78,7 @@ func housekeeping() {
continue
}
db.Lock.RLock()
tPlayerNeedShareCodeUpdate, err := db.Client.Player.Query().Where(
tPlayerNeedShareCodeUpdate, err := db.Player.Query().Where(
player.And(
player.Or(
player.SharecodeUpdatedLTE(time.Now().UTC().Add(time.Duration(-30)*time.Minute)),
@@ -90,21 +86,18 @@ func housekeeping() {
),
player.Not(player.AuthCodeIsNil()),
)).All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Errorf("[HK] Can't query players: %v", err)
continue
}
for _, tPlayer := range tPlayerNeedShareCodeUpdate {
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, db.Lock, conf.Steam.APIKey, rL)
shareCodes, err := utils.GetNewShareCodesForPlayer(tPlayer, conf.Steam.APIKey, rL)
if err != nil {
switch err.(type) {
case utils.AuthcodeUnauthorizedError:
log.Infof("[HK] authCode for player %d is no longer valid", tPlayer.ID)
db.Lock.Lock()
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
db.Lock.Unlock()
if err != nil {
log.Errorf("[HK] Unable to clear authcode for player %d: %v", tPlayer.ID, err)
}
@@ -129,9 +122,7 @@ func housekeeping() {
}
// try parsing demos not parsed
db.Lock.RLock()
tMatches, err := db.Client.Match.Query().Where(match.And(match.DateGT(time.Now().UTC().AddDate(0, 0, -30)), match.DemoParsed(false))).All(context.Background())
db.Lock.RUnlock()
tMatches, err := db.Match.Query().Where(match.And(match.DateGT(time.Now().UTC().AddDate(0, 0, -30)), match.DemoParsed(false))).All(context.Background())
if err != nil {
log.Warningf("[HK] Failure getting matches to retry parsing: %v", err)
continue
@@ -180,7 +171,7 @@ func getPlayerMeta(w http.ResponseWriter, r *http.Request) {
metaStats := new(utils.MetaStatsResponse)
err = rdc.Get(context.Background(), fmt.Sprintf(utils.SideMetaCacheKey, tPlayer.ID), &metaStats)
if err != nil {
metaStats, err = utils.GetMetaStats(tPlayer, db.Lock)
metaStats, err = utils.GetMetaStats(tPlayer)
if err != nil {
log.Infof("[GPM] Unable to get MetaStats: %v", err)
w.WriteHeader(http.StatusInternalServerError)
@@ -221,7 +212,7 @@ func getPlayerMeta(w http.ResponseWriter, r *http.Request) {
for _, p := range append(metaStats.BestMates, metaStats.MostMates...) {
if p.Player.Name == "" {
tP, err := db.Client.Player.Get(context.Background(), p.Player.SteamID64)
tP, err := db.Player.Get(context.Background(), p.Player.SteamID64)
if err != nil {
log.Warningf("[GPM] Failure getting player: %v", err)
w.WriteHeader(http.StatusInternalServerError)
@@ -289,13 +280,9 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
var tMatches []*ent.Match
if !offsetTime.IsZero() {
db.Lock.RLock()
tMatches, err = tPlayer.QueryMatches().Where(match.DateLT(offsetTime)).Order(ent.Desc(match.FieldDate)).Limit(10).All(context.Background())
db.Lock.RUnlock()
} else {
db.Lock.RLock()
tMatches, err = tPlayer.QueryMatches().Order(ent.Desc(match.FieldDate)).Limit(10).All(context.Background())
db.Lock.RUnlock()
}
if err != nil || len(tMatches) == 0 {
log.Debugf("[GP] No matches found for player %s", id)
@@ -311,7 +298,7 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
metaStats := new(utils.MatchStats)
err = rdc.Get(context.Background(), fmt.Sprintf(utils.MatchMetaCacheKey, tPlayer.ID), &metaStats)
if err != nil {
wins, ties, losses, err := utils.GetMatchStats(tPlayer, db.Lock)
wins, ties, losses, err := utils.GetMatchStats(tPlayer)
if err != nil {
log.Errorf("[GP] Error retrieving match-stats for player %s: %v", id, err)
w.WriteHeader(http.StatusInternalServerError)
@@ -358,14 +345,12 @@ func getPlayer(w http.ResponseWriter, r *http.Request) {
Parsed: iMatch.DemoParsed,
}
db.Lock.RLock()
tStats, err := iMatch.QueryStats().Modify(func(s *sql.Selector) {
s.Select(stats.FieldTeamID, stats.FieldKills, stats.FieldDeaths, stats.FieldAssists, stats.FieldHeadshot,
stats.FieldMvp, stats.FieldScore, stats.FieldMk2, stats.FieldMk3, stats.FieldMk4, stats.FieldMk5,
stats.FieldRankOld, stats.FieldRankNew, stats.FieldDmgTeam, stats.FieldDmgEnemy)
s.Where(sql.EQ(s.C(stats.PlayersColumn), tPlayer.ID))
}).Only(context.Background())
db.Lock.RUnlock()
if err != nil {
response.Matches = append(response.Matches, mResponse)
continue
@@ -433,7 +418,7 @@ func deletePlayerTrack(w http.ResponseWriter, r *http.Request) {
return
}
_, err = utils.IsAuthCodeValid(tPlayer, db.Lock, conf.Steam.APIKey, "", authCode, nil)
_, err = utils.IsAuthCodeValid(tPlayer, conf.Steam.APIKey, "", authCode, nil)
if err != nil {
switch e := err.(type) {
case utils.AuthcodeUnauthorizedError:
@@ -447,9 +432,7 @@ func deletePlayerTrack(w http.ResponseWriter, r *http.Request) {
}
}
db.Lock.Lock()
err = tPlayer.Update().ClearAuthCode().ClearSharecodeUpdated().Exec(context.Background())
db.Lock.Unlock()
if err != nil {
log.Warningf("[PPT] update player failed: %+v", err)
w.WriteHeader(http.StatusInternalServerError)
@@ -484,7 +467,7 @@ func postPlayerTrack(w http.ResponseWriter, r *http.Request) {
return
}
_, err = utils.IsAuthCodeValid(tPlayer, db.Lock, conf.Steam.APIKey, shareCode, authCode, rL)
_, err = utils.IsAuthCodeValid(tPlayer, conf.Steam.APIKey, shareCode, authCode, rL)
if err != nil {
switch e := err.(type) {
case utils.AuthcodeUnauthorizedError:
@@ -502,9 +485,7 @@ func postPlayerTrack(w http.ResponseWriter, r *http.Request) {
}
}
db.Lock.Lock()
err = tPlayer.Update().SetAuthCode(authCode).Exec(context.Background())
db.Lock.Unlock()
if err != nil {
log.Warningf("[PPT] update player failed: %+v", err)
w.WriteHeader(http.StatusInternalServerError)
@@ -559,9 +540,7 @@ func getMatchRounds(w http.ResponseWriter, r *http.Request) {
return
}
db.Lock.RLock()
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
db.Lock.RUnlock()
tStats, err := db.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
if err != nil {
log.Infof("[GMR] match %d not found: %+v", matchId, err)
w.WriteHeader(http.StatusNotFound)
@@ -571,9 +550,7 @@ func getMatchRounds(w http.ResponseWriter, r *http.Request) {
resp := map[uint]map[string][]uint{}
for _, stat := range tStats {
db.Lock.RLock()
tRoundStats, err := stat.QueryRoundStats().All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Warningf("[GMR] Unable to get RoundStats for player %d: %v", stat.PlayerStats, err)
continue
@@ -610,9 +587,7 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
return
}
db.Lock.RLock()
tStats, err := db.Client.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
db.Lock.RUnlock()
tStats, err := db.Stats.Query().Where(stats.HasMatchesWith(match.ID(matchId))).All(context.Background())
if err != nil {
log.Infof("[GMW] match %d not found: %+v", matchId, err)
w.WriteHeader(http.StatusNotFound)
@@ -628,9 +603,7 @@ func getMatchWeapons(w http.ResponseWriter, r *http.Request) {
}
for _, stat := range tStats {
db.Lock.RLock()
mWs, err := stat.QueryWeaponStats().All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Warningf("[GMW] Unable to get WeaponStats for player %d: %v", stat.PlayerStats, err)
continue
@@ -676,9 +649,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
return
}
db.Lock.RLock()
tMatch, err := db.Client.Match.Query().Where(match.ID(matchId)).Only(context.Background())
db.Lock.RUnlock()
tMatch, err := db.Match.Query().Where(match.ID(matchId)).Only(context.Background())
if err != nil {
log.Infof("[GM] match %d not found: %v", matchId, err)
w.WriteHeader(http.StatusNotFound)
@@ -702,9 +673,7 @@ func getMatch(w http.ResponseWriter, r *http.Request) {
mResponse.ReplayURL = tMatch.ReplayURL
}
db.Lock.RLock()
tStats, err := tMatch.QueryStats().WithPlayers().All(context.Background())
db.Lock.RUnlock()
if err != nil {
log.Errorf("[GM] Unable to find stats for match %d: %v", tMatch.ID, err)
w.WriteHeader(http.StatusInternalServerError)
@@ -810,10 +779,6 @@ func main() {
journalhook.Enable()
}
db = &utils.DBWithLock{
Lock: new(sync.RWMutex),
}
if conf.Db.Driver == "pgx" {
pdb, err := sql.Open("pgx", conf.Db.ConnectTo)
if err != nil {
@@ -821,27 +786,27 @@ func main() {
}
drv := sql.OpenDB(dialect.Postgres, pdb.DB())
db.Client = ent.NewClient(ent.Driver(drv))
db = ent.NewClient(ent.Driver(drv))
} else {
db.Client, err = ent.Open(conf.Db.Driver, conf.Db.ConnectTo)
db, err = ent.Open(conf.Db.Driver, conf.Db.ConnectTo)
if err != nil {
log.Panicf("Failed to open database %s: %v", conf.Db.ConnectTo, err)
}
defer func(Client *ent.Client) {
_ = Client.Close()
}(db.Client)
}(db)
}
if *sqlDebugFlag {
db.Client = db.Client.Debug()
db = db.Debug()
}
if err := db.Client.Schema.Create(
if err := db.Schema.Create(
context.Background(),
migrate.WithDropIndex(true),
migrate.WithDropColumn(true),
); err != nil {
log.Panicf("Automigrate failed: %v", err)
log.Fatalf("Automigrate failed: %v", err)
}
rdb = redis.NewClient(&redis.Options{
@@ -865,8 +830,7 @@ func main() {
Sentry: conf.Steam.Sentry,
LoginKey: conf.Steam.LoginKey,
ServerList: conf.Steam.ServerList,
Db: db.Client,
Lock: db.Lock,
Db: db,
Worker: conf.Parser.Worker,
ApiKey: conf.Steam.APIKey,
RateLimit: rL,