private void ParallelCharacters(List <ImportDto> characters, JobLifeStyleDto lsDto, ConcurrentQueue <ImportDto> processed, ConcurrentQueue <ImportDto> errors) { Parallel.ForEach(characters, new ParallelOptions { MaxDegreeOfParallelism = _bulk }, () => new BeatCharacterLocalDto(), (character, loopState, localDto) => { try { localDto = ProcessModelCharacter(character, lsDto.K, lsDto.lastDto); processed.Enqueue(character); } catch (Exception e) { character.ErrorText = e.ToString(); errors.Enqueue(character); } lsDto.AddConcurrent(localDto); return(localDto); }, (final) => { }); }
public BeatCharactersDto(BillingBeat beat, JobLifeStyleDto ls) : base(beat) { if (beat == null || ls == null) { return; } SumAll = ls.SumAll; ForecastSumAll = ls.ForecastSumAll; Min = ls.Min; ForecastMin = ls.ForecastMin; Max = ls.Max; ForecastMax = ls.ForecastMax; SumRents = ls.SumRents; SumKarma = ls.SumKarma; SumDividends = ls.SumDividends; Insolvent = ls.Insolvent; Irridium = ls.Irridium; Count = ls.Count; }
private string ProcessLifestyle(JobLifeStyleDto dto) { var db = new LifeStyleAppDto(); db.Bronze = dto.Bronze(); db.Silver = dto.Silver(); db.Gold = dto.Gold(); db.Platinum = dto.Platinum(); db.ForecastBronze = dto.ForecastBronze(); db.ForecastSilver = dto.ForecastSilver(); db.ForecastGold = dto.ForecastGold(); db.ForecastPlatinum = dto.ForecastPlatinum(); var settings = IocContainer.Get <ISettingsManager>(); var value = Serialization.Serializer.ToJSON(db); var beat = Serialization.Serializer.ToJSON(dto); settings.SetValue(SystemSettingsEnum.ls_dto, value); settings.SetValue(SystemSettingsEnum.beat_characters_dto, beat); return(beat); }
public BeatCharacterLocalDto ProcessCharacterBeat(int sinId, WorkModelDto workDto, decimal K, JobLifeStyleDto lastdto) { var sw = new Stopwatch(); sw.Start(); var localDto = new BeatCharacterLocalDto(); var sin = BlockCharacter(sinId, s => s.Wallet, s => s.Character, s => s.Passport, s => s.Scoring); SaveContext(); var mir = GetMIR(); decimal income = 0; decimal outcome = 0; var mortagee = GetMortagee(sin.Passport); //ability if (workDto.Dividends1) { var def1 = _settings.GetDecimalValue(SystemSettingsEnum.dividents1_k); var sum = GetDividends(mortagee, 0.01m, def1); AddNewTransfer(mir, sin.Wallet, sum, "Дивиденды *"); income += sum; localDto.SumDividends += sum; } if (workDto.Dividends2) { var def2 = _settings.GetDecimalValue(SystemSettingsEnum.dividents2_k); var sum = GetDividends(mortagee, 0.03m, def2); AddNewTransfer(mir, sin.Wallet, sum, "Дивиденды **"); income += sum; localDto.SumDividends += sum; } if (workDto.Dividends3) { var def3 = _settings.GetDecimalValue(SystemSettingsEnum.dividents3_k); var sum = GetDividends(mortagee, 0.05m, def3); AddNewTransfer(mir, sin.Wallet, sum, "Дивиденды ***"); income += sum; localDto.SumDividends += sum; } //karma if (workDto.KarmaCount > 0) { var avg = lastdto.GetAvergeKarma(); decimal x1 = 0; if (avg != 0) { x1 = (lastdto.GetAvergeRents() * K) / lastdto.GetAvergeKarma(); } else { x1 = (lastdto.GetAvergeRents() * K) / 700; } if (x1 == 0) { x1 = 0.3m; } var karmasum = x1 * workDto.KarmaCount; income += karmasum; localDto.SumKarma += karmasum; AddNewTransfer(mir, sin.Wallet, karmasum, "Пассивный доход"); } var swIncome = Cut(sw); //rentas var rentas = GetList <Renta>(r => r.SinId == sin.Id, r => r.Shop.Wallet, r => r.Sku.Corporation.Wallet, r => r.Sku.Nomenklatura); foreach (var renta in rentas) { ProcessRenta(renta, mir, sin); } var swRentas = Cut(sw); //overdrafts if (sin.Wallet.Balance > 0) { var allOverdrafts = GetList <Transfer>(t => t.Overdraft && t.WalletFromId == sin.Wallet.Id && t.RentaId > 0); foreach (var overdraft in allOverdrafts) { overdraft.Overdraft = false; var closingRenta = Get <Renta>(r => r.Id == overdraft.RentaId, r => r.Sku.Corporation, r => r.Shop.Wallet, r => r.Sku.Nomenklatura); CloseOverdraft(closingRenta, mir, sin); } } var swoverdrafts = Cut(sw); //metatype if (sin.Passport.MetatypeId != sin.OldMetaTypeId) { var scoring = IoC.IocContainer.Get <IScoringManager>(); scoring.OnMetatypeChanged(sin); sin.OldMetaTypeId = sin.Passport.MetatypeId; } //insurance var insurance = GetInsurance(sin.CharacterId); if (insurance?.LifeStyle != sin.OldInsurance) { if ((insurance?.LifeStyle ?? 0) > 0 != (sin.OldInsurance ?? 0) > 0) { var scoring = IoC.IocContainer.Get <IScoringManager>(); scoring.OnInsuranceChanged(sin, (insurance?.LifeStyle ?? 0) > 0); } sin.OldInsurance = insurance?.LifeStyle; } //summary localDto.Scoringvalue = BillingHelper.GetFullScoring(sin.Scoring); //forecast outcome += rentas.Sum(r => BillingHelper.GetFinalPrice(r)); if (workDto.StockGainPercentage > 0) { var stock = outcome * (workDto.StockGainPercentage / 100); income += stock; AddNewTransfer(mir, sin.Wallet, stock, "Игра на бирже"); } localDto.SumRents += outcome; sin.Wallet.IncomeOutcome = income - outcome; if (sin.Wallet.IsIrridium) { localDto.IsIrridium = true; } else { localDto.Balance = sin.Wallet.Balance; localDto.Forecast = BillingHelper.GetForecast(sin.Wallet); } SaveContext(); var swOther = Cut(sw); sw.Stop(); sin.DebugTime = Serialization.Serializer.ToJSON(new { swIncome, swRentas, swoverdrafts, swOther }); UnblockCharacter(sin); return(localDto); }
private BeatCharacterLocalDto ProcessModelCharacter(ImportDto character, decimal K, JobLifeStyleDto lastdto) { var billing = IocContainer.Get <IBillingManager>(); var workModel = new WorkModelDto { Dividends1 = character?.EreminModel?.workModel?.passiveAbilities?.Any(p => p.id == "dividends-1") ?? false, Dividends2 = character?.EreminModel?.workModel?.passiveAbilities?.Any(p => p.id == "dividends-2") ?? false, Dividends3 = character?.EreminModel?.workModel?.passiveAbilities?.Any(p => p.id == "dividends-3") ?? false, StockGainPercentage = character?.EreminModel?.workModel?.billing?.stockGainPercentage ?? 0, KarmaCount = character?.EreminModel?.workModel?.karma?.spent ?? 0 }; var dto = billing.ProcessCharacterBeat(character.Sin.Id, workModel, K, lastdto); try { EreminPushAdapter.SendNotification(character.Sin.Character.Model, "Кошелек", "Экономический пересчет завершен"); } catch (Exception e) { LogException(e); } return(dto); }
private JobLifeDto DoCharactersBeat(JobLifeDto beat) { Console.WriteLine("Запущен пересчет персонажей"); var sins = Factory.Billing.GetActiveSins(s => s.Wallet, s => s.Character); Console.WriteLine($"Обрабатывается {sins.Count} персонажей"); var charactersLoaded = false; var incomeList = new ConcurrentQueue <ImportDto>(); var processedList = new ConcurrentQueue <ImportDto>(); var errorList = new ConcurrentQueue <ImportDto>(); var lastlsDto = BillingHelper.GetBeatDto(); var lsDto = new JobLifeStyleDto(); lsDto.lastDto = lastlsDto; lsDto.K = (Factory.Settings.GetDecimalValue(SystemSettingsEnum.karma_k) / 100); var taskLoad = Task.Run(() => { Console.WriteLine("Пошла внешняя загрузка персонажей"); LoadCharacters(sins, incomeList); Console.WriteLine("Внешняя загрузка персонажей закончена"); charactersLoaded = true; }); var taskProcess = Task.Run(() => { while (!charactersLoaded || !incomeList.IsEmpty) { if (!charactersLoaded && incomeList.Count < _bulk) { Thread.Sleep(100); continue; } var parallelList = new List <ImportDto>(); ImportDto loaded; while (incomeList.TryDequeue(out loaded)) { if (string.IsNullOrEmpty(loaded.ErrorText)) { parallelList.Add(loaded); } else { errorList.Enqueue(loaded); } } Console.WriteLine($"Внутренняя обработка пачки из {parallelList.Count} персонажей"); ParallelCharacters(parallelList, lsDto, processedList, errorList); Console.WriteLine($"Внутренняя обработка пачки из {parallelList.Count} персонажей"); } }); Task.WaitAll(taskLoad, taskProcess); Console.WriteLine("Пересчеты персонажей закончены, записывается история и ошибки"); foreach (var error in errorList) { beat.AddHistory($"ошибка обработки {error.Sin.Character.Model}: {error.ErrorText}"); } try { var values = ProcessLifestyle(lsDto); var message = $"Значения для lifestyle {values}"; beat.AddHistory(message); } catch (Exception e) { beat.AddHistory(e.ToString()); } return(beat); }