using PagerParser.Sites; namespace PagerParser; // Self-explanatory... Hosted background services that periodically fetches // pager messages, tries to parse them, then adds both the raw pager message // as well as the parsed message contents to the DB, ignoring already fetched // messages in the process. public class PagerFetchService : IHostedService { private readonly TimeSpan FetchInterval = TimeSpan.FromMinutes(15); private IServiceProvider serviceProvider; private IPagerMessageParserService parser; private Timer fetchTimer; private PagerMon pagerMon = new(); public PagerFetchService(IServiceProvider serviceProvider, IPagerMessageParserService parser) { this.serviceProvider = serviceProvider; this.parser = parser; fetchTimer = new Timer(Fetch); } public Task StartAsync(CancellationToken cancellationToken) { fetchTimer.Change(TimeSpan.Zero, FetchInterval); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { fetchTimer.Change(Timeout.Infinite, Timeout.Infinite); return Task.CompletedTask; } private void Fetch(object? state) { using var scope = serviceProvider.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); // Fetch pager messages, ignoring message we've already got var messages = pagerMon .Fetch() .Where(m => !db.PagerMessages .Select(m => m.Message) .Contains(m.Message)); // Attempt to parse each newly-fetched message. // Failure to parse isn't critical, as we still keep the raw message. foreach(var message in messages) { message.ParsedMessage = parser.TryParse(message.Message); if(message.ParsedMessage is not null) message.ParsedMessage.GpsPosition = PositionCalculator.GetGpsPosition(message.ParsedMessage); } db.AddRange(messages); db.SaveChanges(); } public void Dispose() => fetchTimer.Dispose(); }