< Summary

Information
Class: Services.ApiServices.ArmtekApi.ArmtekStoreDirectoryHostedService
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/ArmtekApi/ArmtekStoreDirectoryHostedService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 26
Coverable lines: 26
Total lines: 62
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
.ctor(...)100%210%
ExecuteAsync()0%7280%
KeysToRefresh()0%2040%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/ApiServices/ArmtekApi/ArmtekStoreDirectoryHostedService.cs

#LineLine coverage
 1using Microsoft.Extensions.DependencyInjection;
 2using Microsoft.Extensions.Hosting;
 3using OzonDomains.Models;
 4
 5namespace Services.ApiServices.ArmtekApi;
 6
 7/// <summary>Загружает справочники складов Armtek RU/BY при старте приложения и обновляет их в фоне.</summary>
 8public sealed class ArmtekStoreDirectoryHostedService : BackgroundService
 9{
 010    private static readonly TimeSpan StartupDelay = TimeSpan.FromSeconds(10);
 011    private static readonly TimeSpan RefreshInterval = TimeSpan.FromHours(12);
 012    private static readonly TimeSpan RetryInterval = TimeSpan.FromMinutes(1);
 13
 14    private readonly ArmtekStoreDirectory _directory;
 15    private readonly IServiceProvider _services;
 16
 017    public ArmtekStoreDirectoryHostedService(ArmtekStoreDirectory directory, IServiceProvider services)
 18    {
 019        _directory = directory;
 020        _services = services;
 021    }
 22
 23    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 24    {
 25        try
 26        {
 027            await Task.Delay(StartupDelay, stoppingToken);
 028            while (!stoppingToken.IsCancellationRequested)
 29            {
 030                var allLoaded = true;
 031                foreach (var (providerKey, vkorg) in KeysToRefresh())
 32                {
 33                    // Нарастающая пауза после сбоя хранится в справочнике: тик раз в минуту её не обходит.
 034                    if (!_directory.IsLoadDue(providerKey, vkorg))
 35                    {
 036                        allLoaded = false;
 037                        continue;
 38                    }
 39
 040                    allLoaded &= await _directory.LoadAsync(providerKey, vkorg, stoppingToken);
 41                }
 42
 043                await Task.Delay(allLoaded ? RefreshInterval : RetryInterval, stoppingToken);
 44            }
 045        }
 046        catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
 47        {
 48            // Остановка приложения.
 049        }
 050    }
 51
 52    private IEnumerable<(string ProviderKey, string? Vkorg)> KeysToRefresh()
 53    {
 054        var keys = new HashSet<(string, string?)>(_directory.LoadedKeys);
 55        // Без логина Armtek (локальная разработка, тесты) стартовая загрузка бессмысленна.
 056        if (!string.IsNullOrWhiteSpace(_services.GetRequiredService<ArmtekConfig>().User))
 057            keys.Add((ApiSupplierSettings.ArmtekProviderKey, null));
 058        if (!string.IsNullOrWhiteSpace(_services.GetRequiredService<ArmtekByConfig>().User))
 059            keys.Add((ApiSupplierSettings.ArmtekByProviderKey, null));
 060        return keys;
 61    }
 62}