public async IAsyncEnumerable <Nation> GetRecruitableNationsAsync(int number, bool isAPI, EventId id) { _logger.LogInformation(id, LogMessageBuilder.Build(id, $"{number} recruitable nations requested")); var pendingCount = NationManager.GetNationCountByStatusName("pending"); _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Pending: {pendingCount}")); if (number > pendingCount) { number = pendingCount; } for (int i = 0; i < number; i++) { if (currentRNStatus != null && currentRNStatus.CurrentCount > currentRNStatus.FinalCount) { break; } if (IsReceivingRecruitableNations && !isAPI) { currentRNStatus.CurrentCount++; } var nation = await GetRecruitableNationAsync(id, isAPI); if (nation == null) { break; } yield return(nation); } }
private async Task EnsurePoolFilledAsync() { var id = LogEventIdProvider.GetEventIdByType(LoggingEvent.EnsurePoolFilled); List <REGION> regionsToRecruitFrom = await GetRegionToRecruitFromAsync(id); while (IsRecruiting) { bool fillingUp = false; int counter = 0; int pendingCount = NationManager.GetNationCountByStatusName("pending"); while (pendingCount < _config.MinimumRecruitmentPoolSize) { if (!fillingUp) { fillingUp = true; _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Filling up pending pool now from {pendingCount} to {_config.MinimumRecruitmentPoolSize}")); } PoolStatus = "Filling up with random nations"; var regionId = _rnd.Next(regionsToRecruitFrom.Count); var region = regionsToRecruitFrom.ElementAt(regionId); string nationName; do { var nationId = _rnd.Next(region.NATIONNAMES.Count); nationName = region.NATIONNAMES.ElementAt(nationId); }while (await NationManager.IsNationPendingSkippedSendOrFailedAsync(nationName) || await IsNationRecruitableAsync(new Nation() { Name = nationName, StatusTime = DateTime.UtcNow }, id)); var nation = await NationManager.GetNationAsync(nationName); if (nation != null) { await NationManager.SetNationStatusToAsync(nation, "pending"); } else { await NationManager.AddUnknownNationsAsPendingAsync(new List <string>() { nationName }, true); } counter++; pendingCount = NationManager.GetNationCountByStatusName("pending"); _logger.LogDebug(id, LogMessageBuilder.Build(id, $"Added nation '{nationName}' to pending. Now at {pendingCount} from minimum {_config.MinimumRecruitmentPoolSize}.")); } if (fillingUp) { _logger.LogInformation(id, LogMessageBuilder.Build(id, $"Filled up pending pool to minimum. (Added {counter} nations to pending.)")); PoolStatus = "Waiting for new nations"; } await Task.Delay(1800000); //30 min } }
private async Task RecruitAsync() { List <Nation> pendingNations = new List <Nation>(); while (IsRecruiting && _config.EnableRecruitment) { try { if (pendingNations.Count == 0) { if (NationManager.GetNationCountByStatusName("pending") == 0) { _logger.LogWarning("Delaying API recruitment for 15 minutes due to lack of recruitable nations"); RecruitmentStatus = "Throttled: lack of nations"; await Task.Delay(900000); } pendingNations = NationManager.GetNationsByStatusName("reserved_api"); if (pendingNations.Count < 10) { var numberToRequest = 10 - pendingNations.Count; await foreach (var resNation in GetRecruitableNationsAsync(numberToRequest, true, _defaulEventId)) { pendingNations.Add(resNation); } if (pendingNations.Count < numberToRequest) { RecruitmentStatus = "Throttled: lack of of nations"; _logger.LogWarning("Didn't received enough recruitable nations"); } else { RecruitmentStatus = "Fully operational"; } foreach (var pendingNation in pendingNations) { await NationManager.SetNationStatusToAsync(pendingNation, "reserved_api"); } } } var picked = pendingNations.Take(1); var nation = picked.Count() > 0 ? picked.ToArray()[0] : null; if (nation != null) { if (await _apiService.IsNationStatesApiActionReadyAsync(NationStatesApiRequestType.SendRecruitmentTelegram, true)) { if (await IsNationRecruitableAsync(nation, _defaulEventId)) { if (await _apiService.SendRecruitmentTelegramAsync(nation.Name)) { await NationManager.SetNationStatusToAsync(nation, "send"); _logger.LogInformation(_defaulEventId, LogMessageBuilder.Build(_defaulEventId, $"Telegram to {nation.Name} queued successfully.")); } else { _logger.LogWarning(_defaulEventId, LogMessageBuilder.Build(_defaulEventId, $"Sending of a Telegram to {nation.Name} failed.")); await NationManager.SetNationStatusToAsync(nation, "failed"); } } pendingNations.Remove(nation); } } else { _logger.LogCritical(_defaulEventId, LogMessageBuilder.Build(_defaulEventId, "No nation to recruit found.")); } } catch (Exception ex) { _logger.LogError(_defaulEventId, ex, LogMessageBuilder.Build(_defaulEventId, "An error occured.")); } await Task.Delay(60000); } if (!_config.EnableRecruitment) { _logger.LogWarning(_defaulEventId, "Recruitment disabled."); } }