some refactoring

This commit is contained in:
2021-10-30 08:22:05 +02:00
parent 37233be336
commit 268793f0e5
2 changed files with 388 additions and 390 deletions

View File

@@ -16,6 +16,7 @@ import (
"google.golang.org/protobuf/proto"
"io/ioutil"
"os"
"sync"
"time"
)
@@ -48,6 +49,7 @@ type DemoMatchLoader struct {
dp *DemoParser
parseDemo chan *Demo
parseMap map[string]bool
parseMapL *sync.Mutex
cache *cache.Cache
connecting bool
}
@@ -156,6 +158,7 @@ func (d *DemoMatchLoader) Setup(config *DemoMatchLoaderConfig) error {
d.db = config.Db
d.dp = &DemoParser{}
d.parseMap = map[string]bool{}
d.parseMapL = new(sync.Mutex)
d.cache = config.Cache
err := d.dp.Setup(config.Db, config.Worker)
if err != nil {
@@ -298,172 +301,172 @@ func (d *DemoMatchLoader) requestDemoInfo(matchId uint64, conclusionId uint64, t
}
func (d *DemoMatchLoader) gcWorker(apiKey string, rl ratelimit.Limiter) {
for {
select {
case demo := <-d.parseDemo:
if _, ok := d.parseMap[demo.ShareCode]; ok {
log.Infof("[DL] Skipping %s: parsing in progress", demo.ShareCode)
continue
} else {
d.parseMap[demo.ShareCode] = true
}
if !d.GCReady {
log.Infof("[DL] Postponing match %d (%s): GC not ready", demo.MatchId, demo.ShareCode)
time.Sleep(5 * time.Second)
delete(d.parseMap, demo.ShareCode)
d.parseDemo <- demo
continue
}
matchId, _, _, err := DecodeSharecode(demo.ShareCode)
if err != nil || matchId == 0 {
log.Warningf("[DL] Can't parse match with sharecode %s: %v", demo.ShareCode, err)
delete(d.parseMap, demo.ShareCode)
continue
}
iMatch, err := d.db.Match.Get(context.Background(), matchId)
if err != nil {
switch e := err.(type) {
case *ent.NotFoundError:
break
default:
log.Errorf("[DL] Failure trying to lookup match %d in db: %v", matchId, e)
delete(d.parseMap, demo.ShareCode)
continue
}
} else {
if iMatch.DemoParsed == false && iMatch.Date.After(time.Now().UTC().AddDate(0, 0, -30)) {
log.Infof("[DL] Match %d is loaded, but not parsed. Try parsing.", demo.MatchId)
demo.MatchId = matchId
demo.Url = iMatch.ReplayURL
err := d.dp.ParseDemo(demo)
if err != nil {
log.Warningf("[DL] Parsing demo from match %d failed: %v", demo.MatchId, err)
}
delete(d.parseMap, demo.ShareCode)
continue
}
log.Debugf("[DL] Skipped match %d: already parsed", matchId)
delete(d.parseMap, demo.ShareCode)
continue
}
matchDetails, err := d.getMatchDetails(demo.ShareCode)
if err != nil {
log.Warningf("[DL] Failure to get match-details for %d from GC: %v", demo.MatchId, err)
delete(d.parseMap, demo.ShareCode)
continue
}
matchZero := matchDetails.GetMatches()[0]
lastRound := matchZero.GetRoundstatsall()[len(matchZero.Roundstatsall)-1]
var players []*ent.Player
for _, accountId := range lastRound.GetReservation().GetAccountIds() {
tPlayer, err := utils.GetPlayer(d.db, AccountId2SteamId(accountId), apiKey, rl)
if err != nil {
log.Warningf("[DL] Unable to get player for steamid %d: %v", AccountId2SteamId(accountId), err)
continue
}
players = append(players, tPlayer)
}
demo.Url = lastRound.GetMap()
demo.MatchId = matchZero.GetMatchid()
tMatch, err := d.db.Match.Create().
SetID(matchZero.GetMatchid()).
AddPlayers(players...).
SetDate(time.Unix(int64(matchZero.GetMatchtime()), 0).UTC()).
SetMaxRounds(int(lastRound.GetMaxRounds())).
SetDuration(int(lastRound.GetMatchDuration())).
SetShareCode(demo.ShareCode).
SetReplayURL(lastRound.GetMap()).
SetScoreTeamA(int(lastRound.GetTeamScores()[0])).
SetScoreTeamB(int(lastRound.GetTeamScores()[1])).
SetMatchResult(int(lastRound.GetMatchResult())).
Save(context.Background())
if err != nil {
log.Warningf("[DL] Unable to create match %d: %v", matchZero.GetMatchid(), err)
delete(d.parseMap, demo.ShareCode)
continue
}
for i, mPlayer := range players {
var (
teamId int
mk2 uint
mk3 uint
mk4 uint
mk5 uint
)
if i > 4 {
teamId = 2
} else {
teamId = 1
}
var oldKills int32
for _, round := range matchZero.GetRoundstatsall() {
kills, _, _, _, _, _ := playerStatsFromRound(round, mPlayer)
killDiff := kills - oldKills
switch killDiff {
case 2:
mk2++
case 3:
mk3++
case 4:
mk4++
case 5:
mk5++
}
oldKills = kills
}
kills, deaths, assists, hs, score, mvp := playerStatsFromRound(lastRound, mPlayer)
err := d.db.Stats.Create().
SetMatches(tMatch).
SetPlayers(mPlayer).
SetTeamID(teamId).
SetKills(int(kills)).
SetDeaths(int(deaths)).
SetAssists(int(assists)).
SetMvp(uint(mvp)).
SetScore(int(score)).
SetHeadshot(int(hs)).
SetMk2(mk2).
SetMk3(mk3).
SetMk4(mk4).
SetMk5(mk5).
Exec(context.Background())
if err != nil {
log.Warningf("[DL] Unable to create stats for player %d in match %d: %v", mPlayer.ID, tMatch.ID, err)
}
}
// clear cache for player
for _, p := range players {
err = d.cache.Delete(context.Background(), fmt.Sprintf(utils.SideMetaCacheKey, p.ID))
if err != nil {
log.Warningf("[DL] Unable to delete cache key %s: %v", fmt.Sprintf(utils.SideMetaCacheKey, p.ID), err)
}
err = d.cache.Delete(context.Background(), fmt.Sprintf(utils.MatchMetaCacheKey, p.ID))
if err != nil {
log.Warningf("[DL] Unable to delete cache key %s: %v", fmt.Sprintf(utils.MatchMetaCacheKey, p.ID), err)
}
}
err = d.dp.ParseDemo(demo)
if err != nil {
log.Warningf("[DL] Can't queue demo %d for parsing: %v", demo.MatchId, err)
}
delete(d.parseMap, demo.ShareCode)
for demo := range d.parseDemo {
d.parseMapL.Lock()
if _, ok := d.parseMap[demo.ShareCode]; ok {
log.Infof("[DL] Skipping %s: parsing in progress", demo.ShareCode)
d.parseMapL.Unlock()
continue
} else {
d.parseMap[demo.ShareCode] = true
}
d.parseMapL.Unlock()
if !d.GCReady {
log.Infof("[DL] Postponing match %d (%s): GC not ready", demo.MatchId, demo.ShareCode)
time.Sleep(5 * time.Second)
delete(d.parseMap, demo.ShareCode)
d.parseDemo <- demo
continue
}
matchId, _, _, err := DecodeSharecode(demo.ShareCode)
if err != nil || matchId == 0 {
log.Warningf("[DL] Can't parse match with sharecode %s: %v", demo.ShareCode, err)
delete(d.parseMap, demo.ShareCode)
continue
}
iMatch, err := d.db.Match.Get(context.Background(), matchId)
if err != nil {
switch e := err.(type) {
case *ent.NotFoundError:
break
default:
log.Errorf("[DL] Failure trying to lookup match %d in db: %v", matchId, e)
delete(d.parseMap, demo.ShareCode)
continue
}
} else {
if iMatch.DemoParsed == false && iMatch.Date.After(time.Now().UTC().AddDate(0, 0, -30)) {
log.Infof("[DL] Match %d is loaded, but not parsed. Try parsing.", demo.MatchId)
demo.MatchId = matchId
demo.Url = iMatch.ReplayURL
err := d.dp.ParseDemo(demo)
if err != nil {
log.Warningf("[DL] Parsing demo from match %d failed: %v", demo.MatchId, err)
}
delete(d.parseMap, demo.ShareCode)
continue
}
log.Debugf("[DL] Skipped match %d: already parsed", matchId)
delete(d.parseMap, demo.ShareCode)
continue
}
matchDetails, err := d.getMatchDetails(demo.ShareCode)
if err != nil {
log.Warningf("[DL] Failure to get match-details for %d from GC: %v", demo.MatchId, err)
delete(d.parseMap, demo.ShareCode)
continue
}
matchZero := matchDetails.GetMatches()[0]
lastRound := matchZero.GetRoundstatsall()[len(matchZero.Roundstatsall)-1]
var players []*ent.Player
for _, accountId := range lastRound.GetReservation().GetAccountIds() {
tPlayer, err := utils.GetPlayer(d.db, AccountId2SteamId(accountId), apiKey, rl)
if err != nil {
log.Warningf("[DL] Unable to get player for steamid %d: %v", AccountId2SteamId(accountId), err)
continue
}
players = append(players, tPlayer)
}
demo.Url = lastRound.GetMap()
demo.MatchId = matchZero.GetMatchid()
tMatch, err := d.db.Match.Create().
SetID(matchZero.GetMatchid()).
AddPlayers(players...).
SetDate(time.Unix(int64(matchZero.GetMatchtime()), 0).UTC()).
SetMaxRounds(int(lastRound.GetMaxRounds())).
SetDuration(int(lastRound.GetMatchDuration())).
SetShareCode(demo.ShareCode).
SetReplayURL(lastRound.GetMap()).
SetScoreTeamA(int(lastRound.GetTeamScores()[0])).
SetScoreTeamB(int(lastRound.GetTeamScores()[1])).
SetMatchResult(int(lastRound.GetMatchResult())).
Save(context.Background())
if err != nil {
log.Warningf("[DL] Unable to create match %d: %v", matchZero.GetMatchid(), err)
delete(d.parseMap, demo.ShareCode)
continue
}
for i, mPlayer := range players {
var (
teamId int
mk2 uint
mk3 uint
mk4 uint
mk5 uint
)
if i > 4 {
teamId = 2
} else {
teamId = 1
}
var oldKills int32
for _, round := range matchZero.GetRoundstatsall() {
kills, _, _, _, _, _ := playerStatsFromRound(round, mPlayer)
killDiff := kills - oldKills
switch killDiff {
case 2:
mk2++
case 3:
mk3++
case 4:
mk4++
case 5:
mk5++
}
oldKills = kills
}
kills, deaths, assists, hs, score, mvp := playerStatsFromRound(lastRound, mPlayer)
err := d.db.Stats.Create().
SetMatches(tMatch).
SetPlayers(mPlayer).
SetTeamID(teamId).
SetKills(int(kills)).
SetDeaths(int(deaths)).
SetAssists(int(assists)).
SetMvp(uint(mvp)).
SetScore(int(score)).
SetHeadshot(int(hs)).
SetMk2(mk2).
SetMk3(mk3).
SetMk4(mk4).
SetMk5(mk5).
Exec(context.Background())
if err != nil {
log.Warningf("[DL] Unable to create stats for player %d in match %d: %v", mPlayer.ID, tMatch.ID, err)
}
}
// clear cache for player
for _, p := range players {
err = d.cache.Delete(context.Background(), fmt.Sprintf(utils.SideMetaCacheKey, p.ID))
if err != nil {
log.Warningf("[DL] Unable to delete cache key %s: %v", fmt.Sprintf(utils.SideMetaCacheKey, p.ID), err)
}
err = d.cache.Delete(context.Background(), fmt.Sprintf(utils.MatchMetaCacheKey, p.ID))
if err != nil {
log.Warningf("[DL] Unable to delete cache key %s: %v", fmt.Sprintf(utils.MatchMetaCacheKey, p.ID), err)
}
}
err = d.dp.ParseDemo(demo)
if err != nil {
log.Warningf("[DL] Can't queue demo %d for parsing: %v", demo.MatchId, err)
}
delete(d.parseMap, demo.ShareCode)
}
}