diff --git a/src/GoDaddyDDNS/Abstractions/IDynamicDNSService.cs b/src/GoDaddyDDNS/Abstractions/IDynamicDNSService.cs index 400550d..6923a7a 100644 --- a/src/GoDaddyDDNS/Abstractions/IDynamicDNSService.cs +++ b/src/GoDaddyDDNS/Abstractions/IDynamicDNSService.cs @@ -1,10 +1,11 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; namespace GoDaddyDDNS.Abstractions { public interface IDynamicDNSService { - Task Initialize(); - Task Execute(); + Task Initialize(CancellationToken cancellationToken); + Task Execute(CancellationToken cancellationToken); } } diff --git a/src/GoDaddyDDNS/Abstractions/IGoDaddyConnector.cs b/src/GoDaddyDDNS/Abstractions/IGoDaddyConnector.cs index 9a99d3e..c4698f7 100644 --- a/src/GoDaddyDDNS/Abstractions/IGoDaddyConnector.cs +++ b/src/GoDaddyDDNS/Abstractions/IGoDaddyConnector.cs @@ -1,11 +1,12 @@ using GoDaddyDDNS.Models; +using System.Threading; using System.Threading.Tasks; namespace GoDaddyDDNS.Abstractions { internal interface IGoDaddyConnector { - Task GetRecords(); - Task UpdateRecords(DNSRecord[] records); + Task GetRecords(CancellationToken cancellationToken); + Task UpdateRecords(DNSRecord[] records, CancellationToken cancellationToken); } } diff --git a/src/GoDaddyDDNS/Abstractions/IPublicIPTracker.cs b/src/GoDaddyDDNS/Abstractions/IPublicIPTracker.cs index 82d477f..d6a3202 100644 --- a/src/GoDaddyDDNS/Abstractions/IPublicIPTracker.cs +++ b/src/GoDaddyDDNS/Abstractions/IPublicIPTracker.cs @@ -1,9 +1,10 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; namespace GoDaddyDDNS.Abstractions { internal interface IPublicIPTracker { - Task Get(); + Task Get(CancellationToken cancellationToken); } } diff --git a/src/GoDaddyDDNS/Services/DynamicDNSService.cs b/src/GoDaddyDDNS/Services/DynamicDNSService.cs index 70ebaf1..79e64bb 100644 --- a/src/GoDaddyDDNS/Services/DynamicDNSService.cs +++ b/src/GoDaddyDDNS/Services/DynamicDNSService.cs @@ -3,6 +3,7 @@ using GoDaddyDDNS.Models; using Microsoft.Extensions.Logging; using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace GoDaddyDDNS.Services @@ -23,19 +24,19 @@ namespace GoDaddyDDNS.Services _goDaddyConnector=goDaddyConnector; } - public async Task Initialize() + public async Task Initialize(CancellationToken cancellationToken) { // check records - var records = await _goDaddyConnector.GetRecords(); + var records = await _goDaddyConnector.GetRecords(cancellationToken); if (records == null || records.Length == 0) throw new Exception("No valid record found."); DNSRecords = records; PublicIP = records.First().Data; } - public async Task Execute() + public async Task Execute(CancellationToken cancellationToken) { - var publicIP = await _publicIPTracker.Get(); + var publicIP = await _publicIPTracker.Get(cancellationToken); if (PublicIP != publicIP) { _logger.LogWarning($"[{DateTime.Now}]: Public IP has changed from '{PublicIP}' to '{publicIP}'"); @@ -45,7 +46,7 @@ namespace GoDaddyDDNS.Services return record; }).ToArray(); - await _goDaddyConnector.UpdateRecords(newRecords); + await _goDaddyConnector.UpdateRecords(newRecords, cancellationToken); PublicIP = publicIP; DNSRecords = newRecords; diff --git a/src/GoDaddyDDNS/Services/GoDaddyConnector.cs b/src/GoDaddyDDNS/Services/GoDaddyConnector.cs index 2029989..c17b6a4 100644 --- a/src/GoDaddyDDNS/Services/GoDaddyConnector.cs +++ b/src/GoDaddyDDNS/Services/GoDaddyConnector.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace GoDaddyDDNS.Services @@ -43,12 +44,12 @@ namespace GoDaddyDDNS.Services private string GetRecordRoute(string name) => _recordRoute.Replace("{domain}", _domain).Replace("{type}", _recordType).Replace("{name}", name); - public async Task GetRecords() + public async Task GetRecords(CancellationToken cancellationToken) { var list = new List(); foreach (var name in _records) { - var dnsRecord = await GetRecord(name); + var dnsRecord = await GetRecord(name, cancellationToken); if (dnsRecord == null) _logger.LogWarning($"The record '{name}' was not found and will be ignored."); else @@ -57,12 +58,12 @@ namespace GoDaddyDDNS.Services return list.ToArray(); } - private async Task GetRecord(string name) + private async Task GetRecord(string name, CancellationToken cancellationToken) { var route = GetRecordRoute(name); - using (var response = await _httpClient.GetAsync(route)) + using (var response = await _httpClient.GetAsync(route, cancellationToken).ConfigureAwait(false)) { - var resultAsString = await response.Content.ReadAsStringAsync(); + var resultAsString = await response.Content.ReadAsStringAsync(cancellationToken); if (response.IsSuccessStatusCode) { var result = JsonConvert.DeserializeObject(resultAsString); @@ -79,13 +80,13 @@ namespace GoDaddyDDNS.Services } } - public async Task UpdateRecords(DNSRecord[] records) + public async Task UpdateRecords(DNSRecord[] records, CancellationToken cancellationToken) { foreach (var record in records) - await UpdateRecord(record); + await UpdateRecord(record, cancellationToken); } - private async Task UpdateRecord(DNSRecord record) + private async Task UpdateRecord(DNSRecord record, CancellationToken cancellationToken) { var route = GetRecordRoute(record.Name); var data = JsonConvert.SerializeObject(new DNSRecord[] { record }, new JsonSerializerSettings @@ -95,12 +96,12 @@ namespace GoDaddyDDNS.Services var content = new StringContent(data, Encoding.UTF8, "application/json"); - using (var response = await _httpClient.PutAsync(route, content)) + using (var response = await _httpClient.PutAsync(route, content, cancellationToken)) { if (response.IsSuccessStatusCode) return; - var resultAsString = await response.Content.ReadAsStringAsync(); + var resultAsString = await response.Content.ReadAsStringAsync(cancellationToken); var error = JsonConvert.DeserializeObject(resultAsString); throw new Exception($"{error.Code}: {error.Message}"); }; diff --git a/src/GoDaddyDDNS/Services/PublicIPTracker.cs b/src/GoDaddyDDNS/Services/PublicIPTracker.cs index 6bc57a6..167a2df 100644 --- a/src/GoDaddyDDNS/Services/PublicIPTracker.cs +++ b/src/GoDaddyDDNS/Services/PublicIPTracker.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using System; using System.Net; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; namespace GoDaddyDDNS.Services @@ -21,14 +22,14 @@ namespace GoDaddyDDNS.Services _publicIPProviders = configuration.GetSection("PublicIPProviders").Get(); } - public async Task Get() + public async Task Get(CancellationToken cancellationToken) { if (_publicIPProviders == null || _publicIPProviders.Length == 0) throw new Exception("No public IP provider is configured."); foreach (var provider in _publicIPProviders) { - var ip = await GetIP(provider); + var ip = await GetIP(provider, cancellationToken); if (ip != null) return ip; } @@ -36,13 +37,13 @@ namespace GoDaddyDDNS.Services throw new Exception("The public IP could not be obtained from any of the configured providers."); } - private async Task GetIP(string providerUrl) + private async Task GetIP(string providerUrl, CancellationToken cancellationToken) { string ip = null; - using (var response = await _httpClient.GetAsync(providerUrl)) + using (var response = await _httpClient.GetAsync(providerUrl, cancellationToken).ConfigureAwait(false)) { if (response.IsSuccessStatusCode) - ip = await response.Content.ReadAsStringAsync(); + ip = await response.Content.ReadAsStringAsync(cancellationToken); else return null; } diff --git a/src/GoDaddyDDNS/Worker.cs b/src/GoDaddyDDNS/Worker.cs index 5c0728d..c0e3b1d 100644 --- a/src/GoDaddyDDNS/Worker.cs +++ b/src/GoDaddyDDNS/Worker.cs @@ -29,15 +29,27 @@ namespace GoDaddyDDNS while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - await _dynamicDNSService.Execute(); + await Execute(stoppingToken); await Task.Delay(_delay, stoppingToken); } } + private async Task Execute(CancellationToken cancellationToken) + { + try + { + await _dynamicDNSService.Execute(cancellationToken); + } + catch (Exception e) + { + _logger.LogError(e, "An unexpected error was encountered during execution."); + } + } + public override async Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Starting worker..."); - await _dynamicDNSService.Initialize(); + await _dynamicDNSService.Initialize(cancellationToken); await base.StartAsync(cancellationToken); }