using AS1024.GeoFeed.Interfaces; using Microsoft.EntityFrameworkCore; namespace AS1024.GeoFeed.GeoFeedLocalCache { public class GeoFeedCacheService : IHostedService { CancellationToken _cancellationToken; private readonly ILogger logger; private readonly IGeoFeedProvider feedProvider; private readonly GeoFeedCacheDbContext dbContext; public GeoFeedCacheService(ILogger logger, IGeoFeedProvider feedProvider, GeoFeedCacheDbContext dbContext) { this.logger = logger; this.feedProvider = feedProvider; this.dbContext = dbContext; } public Task StartAsync(CancellationToken cancellationToken) { _ = StartPerioidicSync(); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public async Task StartPerioidicSync() { if (dbContext.Database.GetPendingMigrations().Any()) await dbContext.Database.MigrateAsync(); List geoFeedCacheEntry = []; while (!_cancellationToken.IsCancellationRequested) { await Task.Delay(TimeSpan.FromMinutes(30)); logger.LogInformation("Running on disk fallback cache process..."); try { 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); await dbContext.SaveChangesAsync(); } catch (Exception ex) { logger.LogWarning("On disk cache failed to run. Waiting on 30 minutes before retry..."); } } return false; } } }