using AS1024.GeoFeed.Core.Interfaces; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System.Runtime.CompilerServices; namespace AS1024.GeoFeed.Core.GeoFeedLocalCache { public class GeoFeedCacheService : IHostedService { private readonly ILogger logger; private readonly IGeoFeedProvider feedProvider; private readonly IHost host; public GeoFeedCacheService(ILogger logger, IGeoFeedProvider feedProvider, IHost host) { this.logger = logger; this.feedProvider = feedProvider; this.host = host; } public Task StartAsync(CancellationToken cancellationToken) { _ = StartPerioidicSync(cancellationToken); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public async Task StartPerioidicSync(CancellationToken Token) { await DBContextMigrate(); List geoFeedCacheEntry = []; while (!Token.IsCancellationRequested) { logger.LogInformation("Running on disk fallback cache process..."); try { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var results = await feedProvider.GetGeoFeedData(); results.ForEach(x => { geoFeedCacheEntry.Add(new() { Prefix = x.Prefix, GeolocCity = x.GeolocCity, GeolocCountry = x.GeolocCountry, GeolocHasLocation = x.GeolocHasLocation, GeolocPostalCode = x.GeolocPostalCode, GeolocRegion = x.GeolocRegion }); }); if (dbContext.GeoFeedCacheEntries.Any()) { dbContext.GeoFeedCacheEntries.RemoveRange(dbContext.GeoFeedCacheEntries.ToArray()); } await dbContext.AddRangeAsync(geoFeedCacheEntry, Token); await dbContext.SaveChangesAsync(Token); } catch (Exception ex) { logger.LogWarning("On disk cache failed to run. Waiting on 30 minutes before retry..."); } await Task.Delay(TimeSpan.FromMinutes(30)); } return false; } private async Task DBContextMigrate() { using IServiceScope scope = host.Services.CreateScope(); using GeoFeedCacheDbContext? dbContext = scope.ServiceProvider.GetService(); #pragma warning disable CS8602 // Dereference of a possibly null reference. if (dbContext.Database.GetPendingMigrations().Any()) { await dbContext.Database.MigrateAsync(); } #pragma warning restore CS8602 // Dereference of a possibly null reference. } } }