aboutsummaryrefslogtreecommitdiff
path: root/PagerFetchService.cs
blob: 97a03d5b5714f6a0a210c37b3f2188cd64affa90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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<PagerContext>();

        // 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();
}