private async Task ladderTask(
            CancellationToken stoppingToken,
            string currentLeagueName, int limit = 50, int offset = 0, string accountName = null)
        {
            var payloads = new List <PoeFetcher.CharFetchResultPayload> {
            };

            await foreach (var payload in PoeFetcher.GetCharFetchResultPayloadFromLadderIterator(currentLeagueName, limit, offset, accountName))
            {
                if (stoppingToken.IsCancellationRequested)
                {
                    return;
                }
                payloads.Add(payload);
            }
            System.GC.Collect();
            PobUtils.try_malloc_trim(0);
            // gc for run pob, need 500M+ memory.
            var pchars = new List <PoeCharacterModel> {
            };

            using (var luaState = PobUtils.CreateLuaState())
            {
                foreach (var payload in payloads)
                {
                    if (stoppingToken.IsCancellationRequested)
                    {
                        break;
                    }
                    PoeCharacterModel pchar = payload.ToCharacterModel(luaState);
                    if (pchar != null)
                    {
                        pchars.Add(pchar);
                    }
                }
            }
            // force clear 500M+ memory
            System.GC.Collect();
            PobUtils.try_malloc_trim(0);
            foreach (var pchar in pchars)
            {
                _logger.LogInformation($"Upserting {pchar.AccountName} / {pchar.CharacterName}");
                await characterService.DefaultUpsert(pchar);
            }
        }
        private void ForceUpdateCharactersPob(CancellationToken stoppingToken)
        {
            List <PoeCharacterModel> _chars =
                PoeContext.Characters
                .Select(c => new PoeCharacterModel {
                CharacterId = c.CharacterId, PobCode = c.PobCode
            })
                .ToList();

            foreach (var _c in _chars)
            {
                if (stoppingToken.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    string         newPobXml   = PobUtils.GetBuildXmlByXml(PobUtils.CodeToXml(_c.PobCode));
                    string         nextPobCode = PobUtils.XmlToCode(newPobXml);
                    PathOfBuilding nextPob     = PobUtils.XmlToPob(newPobXml);
                    _c.PobCode = nextPobCode;
                    _c.Pob     = nextPob;
                    _c.Pob     = PobUtils.XmlToPob(PobUtils.CodeToXml(_c.PobCode));
                    using (var db = new PoeDbContext())
                    {
                        db.Characters.Attach(_c);
                        db.Entry(_c).Property(x => x.PobCode).IsModified = true;
                        db.Entry(_c).Property(x => x.Pob).IsModified     = true;
                        db.SaveChanges();
                    }
                }
                catch (System.Exception e)
                {
                    _logger.LogError(e.ToString());
                }
            }
        }
Exemple #3
0
            public PoeCharacterModel ToCharacterModel(NLua.Lua luaState)
            {
                var    entry    = ladderEntry;
                string buildXml = PobUtils.GetBuildXmlByJsons(passivesJson, itemsJson, luaState);

                PathOfBuilding tryGetPob()
                {
                    PathOfBuilding pob;

                    try
                    {
                        pob = PobUtils.XmlToPob(buildXml);
                    }
                    catch (System.Exception e)
                    {
                        // TODO
                        // Log entry and e
                        if (e is System.InvalidOperationException || e is System.Xml.XmlException)
                        {
                            pob = null;
                            System.Console.WriteLine(e.ToString());
                        }
                        else
                        {
                            throw;
                        }
                    }
                    return(pob);
                }

                PathOfBuilding pob = tryGetPob();

                if (pob != null)
                {
                    PoeItems    items    = JsonConvert.DeserializeObject <PoeItems>(itemsJson);
                    PoePassives passives = JsonConvert.DeserializeObject <PoePassives>(passivesJson);
                    string      code     = PobUtils.XmlToCode(buildXml);
                    var         poeChar  = new PoeCharacterModel()
                    {
                        CharacterId   = entry.Character.Id,
                        CharacterName = entry.Character.Name,
                        LeagueName    = leagueName,
                        Account       = entry.Account,
                        AccountName   = entry.Account != null ? entry.Account.Name : null,
                        Level         = entry.Character.Level,
                        Class         = entry.Character.Class,
                        Depth         = entry.Character.Depth ?? new PoeDepth {
                            Solo = 0, Default = 0
                        },
                        Dead           = entry.Dead,
                        Online         = entry.Online,
                        Rank           = entry.Rank,
                        Experience     = entry.Character.Experience,
                        LifeUnreserved = pob.GetStat("LifeUnreserved"),
                        EnergyShield   = pob.GetStat("EnergyShield"),
                        Pob            = pob,
                        PobCode        = code,
                        Items          = new List <PoeItem>()
                        {
                        }.Concat(items.items.Concat(passives.items.Select(i => i.ToPoeItem()))).ToList(),
                        UpdatedAt = System.DateTime.UtcNow,
                    };
                    return(poeChar);
                }
                else
                {
                    return(null);
                }
            }
        private async Task FetchAndUpsertCharacters(CancellationToken stoppingToken, string targetLeagueName)
        {
            int  limit         = 50;
            long limitCharRows = 9000;
            long numCharRows   = await characterService.GetNumCharacters();

            if (numCharRows >= limitCharRows)
            {
                _logger.LogInformation($"Full characters reach limit rows {limitCharRows}, current: {numCharRows} only update.");
                var entityType   = PoeContext.Model.FindEntityType(typeof(PoeCharacterModel));
                var schema       = entityType.GetSchema();
                var tableName    = entityType.GetTableName();
                var sql          = $@"
        SELECT ""AccountName"", ""LeagueName"", ""CharacterId"", ""Account""
        FROM ""{tableName}""
        ORDER BY RANDOM()
        LIMIT {limit}
        ";
                var pchars       = PoeContext.Database.GetDbConnection().Query <PoeCharacterModel>(sql).ToList();
                var fetchResults = new List <PoeFetcher.CharFetchResultPayload> {
                };
                foreach (PoeCharacterModel pchar in pchars)
                {
                    // Not support specific character from ladder only by accountName.
                    await foreach (var res in PoeFetcher.GetCharFetchResultPayloadFromLadderIterator(pchar.LeagueName, 5, 0, pchar.AccountName))
                    {
                        if (res != null && res.ladderEntry != null && res.ladderEntry.Account == null)
                        {
                            res.ladderEntry.Account = pchar.Account;
                        }
                        fetchResults.Add(res);
                    }
                    await Task.Delay(500, stoppingToken);
                }
                fetchResults = fetchResults.Where(res =>
                {
                    return(pchars.Any(p =>
                    {
                        return p.CharacterId == res.ladderEntry.Character.Id;
                    }));
                }
                                                  ).ToList();
                System.GC.Collect();
                PobUtils.try_malloc_trim(0);
                List <PoeCharacterModel> newPchars;
                using (var luaState = PobUtils.CreateLuaState())
                {
                    newPchars = fetchResults
                                .Select(res => res.ToCharacterModel(luaState))
                                .Where(pchar => pchar != null)
                                .ToList();
                }
                System.GC.Collect();
                PobUtils.try_malloc_trim(0);
                foreach (var pchar in newPchars)
                {
                    _logger.LogInformation($"Upserting {pchar.AccountName} / {pchar.CharacterName}");
                    await characterService.DefaultUpsert(pchar);
                }
            }
            else
            {
                int currentMaxRank = await PoeContext.Characters.MaxAsync(c => (int?)c.Rank) ?? 0;

                int    targetMax         = 15000;
                int    maxDelta          = targetMax - currentMaxRank;
                string currentLeagueName = targetLeagueName;
                if (maxDelta <= limit)
                {
                    System.Random rnd    = new System.Random();
                    int           offset = rnd.Next(0, targetMax - limit);
                    await ladderTask(stoppingToken, currentLeagueName, limit, offset);
                }
                else
                {
                    int offset = currentMaxRank;
                    await ladderTask(stoppingToken, currentLeagueName, limit, offset);
                }
            }
        }