removed locks, switching to WAL for SQLite default
This commit is contained in:
78
main.go
78
main.go
@@ -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,
|
||||
|
Reference in New Issue
Block a user