diff --git a/FastGithub/DnsHostedService.cs b/FastGithub/DnsHostedService.cs index 2b1b81f..91d7e5d 100644 --- a/FastGithub/DnsHostedService.cs +++ b/FastGithub/DnsHostedService.cs @@ -44,18 +44,16 @@ namespace FastGithub var domain = question.Name.ToString(); if (domain.Contains("github", StringComparison.OrdinalIgnoreCase)) { - var contexts = this.githubScanService.Result - .Where(item => item.Domain == domain) - .OrderBy(item => item.HttpElapsed); - - foreach (var context in contexts) + var ttl = TimeSpan.FromMinutes(2d); + var addressArray = this.githubScanService.FindAddress(domain); + foreach (var address in addressArray) { - var record = new IPAddressResourceRecord(question.Name, context.Address, TimeSpan.FromMinutes(2d)); + var record = new IPAddressResourceRecord(question.Name, address, ttl); response.AnswerRecords.Add(record); - this.logger.LogWarning(record.ToString()); } - return Task.FromResult(response); + var addressString = string.Join(',', addressArray.Select(a => a.ToString())); + this.logger.LogInformation($"{domain}=>{addressString}"); } } diff --git a/FastGithub/GithubContext.cs b/FastGithub/GithubContext.cs index 5764c9e..ff467e0 100644 --- a/FastGithub/GithubContext.cs +++ b/FastGithub/GithubContext.cs @@ -3,15 +3,15 @@ using System.Net; namespace FastGithub { - class GithubContext + class GithubContext : IEquatable { - public string Domain { get; } + public string Domain { get; } - public IPAddress Address { get; } + public IPAddress Address { get; } public TimeSpan? HttpElapsed { get; set; } - public GithubContext(string domain,IPAddress address) + public GithubContext(string domain, IPAddress address) { this.Domain = domain; this.Address = address; @@ -21,5 +21,20 @@ namespace FastGithub { return $"{Address}\t{Domain}\t# {HttpElapsed}"; } + + public override bool Equals(object? obj) + { + return obj is GithubContext other && this.Equals(other); + } + + public bool Equals(GithubContext? other) + { + return other != null && other.Address.Equals(this.Address) && other.Domain == this.Domain; + } + + public override int GetHashCode() + { + return HashCode.Combine(this.Domain, this.Address); + } } } diff --git a/FastGithub/GithubContextHashSet.cs b/FastGithub/GithubContextHashSet.cs new file mode 100644 index 0000000..d4bd3f2 --- /dev/null +++ b/FastGithub/GithubContextHashSet.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace FastGithub +{ + class GithubContextHashSet : HashSet + { + public readonly object SyncRoot = new(); + } +} diff --git a/FastGithub/GithubScanService.cs b/FastGithub/GithubScanService.cs index ba6df02..1d2dbe7 100644 --- a/FastGithub/GithubScanService.cs +++ b/FastGithub/GithubScanService.cs @@ -1,5 +1,6 @@ -using System.Collections.Concurrent; +using Microsoft.Extensions.Logging; using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; @@ -9,15 +10,17 @@ namespace FastGithub { private readonly GithubMetaService metaService; private readonly GithubScanDelegate scanDelegate; - - public ConcurrentQueue Result { get; } = new(); + private readonly ILogger logger; + private readonly GithubContextHashSet results = new(); public GithubScanService( GithubMetaService metaService, - GithubScanDelegate scanDelegate) + GithubScanDelegate scanDelegate, + ILogger logger) { this.metaService = metaService; this.scanDelegate = scanDelegate; + this.logger = logger; } public async Task ScanAllAsync(CancellationToken cancellationToken = default) @@ -25,26 +28,50 @@ namespace FastGithub var meta = await this.metaService.GetMetaAsync(cancellationToken); if (meta != null) { - this.Result.Clear(); var scanTasks = meta.ToGithubContexts().Select(ctx => ScanAsync(ctx)); await Task.WhenAll(scanTasks); } + + this.logger.LogInformation("完全扫描完成"); + + async Task ScanAsync(GithubContext context) + { + await this.scanDelegate(context); + if (context.HttpElapsed != null) + { + lock (this.results.SyncRoot) + { + this.results.Add(context); + } + } + } } public async Task ScanResultAsync() { - while (this.Result.TryDequeue(out var context)) + GithubContext[] contexts; + lock (this.results.SyncRoot) { - await this.ScanAsync(context); + contexts = this.results.ToArray(); } + + foreach (var context in contexts) + { + await this.scanDelegate(context); + } + + this.logger.LogInformation("结果扫描完成"); } - private async Task ScanAsync(GithubContext context) + public IPAddress[] FindAddress(string domain) { - await this.scanDelegate(context); - if (context.HttpElapsed != null) + lock (this.results.SyncRoot) { - this.Result.Enqueue(context); + return this.results + .Where(item => item.Domain == domain && item.HttpElapsed != null) + .OrderBy(item => item.HttpElapsed) + .Select(item => item.Address) + .ToArray(); } } } diff --git a/FastGithub/Properties/launchSettings.json b/FastGithub/Properties/launchSettings.json index 2d7291b..b100c0a 100644 --- a/FastGithub/Properties/launchSettings.json +++ b/FastGithub/Properties/launchSettings.json @@ -7,7 +7,7 @@ "launchBrowser": true, "environmentVariables": { "DOTNET_ENVIRONMENT": "Development", - "Logging__LogLevel__Default": "Information" + "Logging__LogLevel__Default": "Trace" } } }