From e974635cfb48a2b3a82be621f53b87642cea74ce Mon Sep 17 00:00:00 2001 From: Jeff Leung Date: Mon, 8 Jan 2024 09:57:37 -0800 Subject: [PATCH] Break it out to individual files and initial cache service --- .../GeoFeedBuilder/GeoFeedCacheService.cs | 63 ---------------- .../GeoFeedCacheDbContext.cs | 15 ++++ .../GeoFeedLocalCache/GeoFeedCacheEntry.cs | 12 +++ .../GeoFeedLocalCache/GeoFeedCacheService.cs | 75 +++++++++++++++++++ .../GeoFeedDesignTimeMigration.cs | 16 ++++ 5 files changed, 118 insertions(+), 63 deletions(-) delete mode 100644 AS1024.GeoFeed/GeoFeedBuilder/GeoFeedCacheService.cs create mode 100644 AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheDbContext.cs create mode 100644 AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheEntry.cs create mode 100644 AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheService.cs create mode 100644 AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedDesignTimeMigration.cs diff --git a/AS1024.GeoFeed/GeoFeedBuilder/GeoFeedCacheService.cs b/AS1024.GeoFeed/GeoFeedBuilder/GeoFeedCacheService.cs deleted file mode 100644 index ceaa071..0000000 --- a/AS1024.GeoFeed/GeoFeedBuilder/GeoFeedCacheService.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using AS1024.GeoFeed.Models; -using AS1024.GeoFeed.GeoFeedBuilder; -using Microsoft.EntityFrameworkCore; -using AS1024.GeoFeed.Interfaces; - -namespace AS1024.GeoFeed.GeoFeedCacheService -{ - public class GeoFeedCacheService : IHostedService - { - CancellationToken _cancellationToken; - private readonly ILogger logger; - private readonly IGeoFeedProvider feedProvider; - - public GeoFeedCacheService(ILogger logger, - IGeoFeedProvider feedProvider) - { - this.logger = logger; - this.feedProvider = feedProvider; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - _ = StartPerioidicSync(); - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - public async Task StartPerioidicSync(){ - List geoFeedCacheEntry = []; - while (!_cancellationToken.IsCancellationRequested) { - await Task.Delay(TimeSpan.FromMinutes(30)); - logger.LogInformation("Running on disk fallback cache process..."); - 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 - }); - }); - } - return false; - } - } - - public class GeoFeedCacheEntry : IPGeoFeed { - [Key] - public int Id { get; set; } - } - - public class GeoFeedCacheDbContext : DbContext { - public virtual DbSet GeoFeedCacheEntries {get;set;} - } -} \ No newline at end of file diff --git a/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheDbContext.cs b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheDbContext.cs new file mode 100644 index 0000000..d23188e --- /dev/null +++ b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheDbContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; + +namespace AS1024.GeoFeed.GeoFeedLocalCache +{ + public class GeoFeedCacheDbContext : DbContext + { + public GeoFeedCacheDbContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet GeoFeedCacheEntries { get; set; } + } + +} \ No newline at end of file diff --git a/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheEntry.cs b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheEntry.cs new file mode 100644 index 0000000..363692f --- /dev/null +++ b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheEntry.cs @@ -0,0 +1,12 @@ +using AS1024.GeoFeed.Models; +using System.ComponentModel.DataAnnotations; + +namespace AS1024.GeoFeed.GeoFeedLocalCache +{ + public class GeoFeedCacheEntry : IPGeoFeed + { + [Key] + public int Id { get; set; } + } + +} \ No newline at end of file diff --git a/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheService.cs b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheService.cs new file mode 100644 index 0000000..48dde93 --- /dev/null +++ b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedCacheService.cs @@ -0,0 +1,75 @@ +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; + } + } +} \ No newline at end of file diff --git a/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedDesignTimeMigration.cs b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedDesignTimeMigration.cs new file mode 100644 index 0000000..f79d0b6 --- /dev/null +++ b/AS1024.GeoFeed/GeoFeedLocalCache/GeoFeedDesignTimeMigration.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +namespace AS1024.GeoFeed.GeoFeedLocalCache +{ + public class GeoFeedDesignTimeMigration : IDesignTimeDbContextFactory + { + public GeoFeedCacheDbContext CreateDbContext(string[] args) + { + var builder = new DbContextOptionsBuilder(); + builder.UseSqlite("Data Source=migratedb.db"); + return new GeoFeedCacheDbContext(builder.Options); + } + } + +} \ No newline at end of file