增加扫描结果保存和加载功能

This commit is contained in:
xljiulang 2021-07-15 21:47:01 +08:00
parent 1a3918cdf8
commit b81b41e114
5 changed files with 111 additions and 10 deletions

View File

@ -77,9 +77,9 @@ namespace FastGithub
store.Close(); store.Close();
} }
} }
catch (Exception ex) catch (Exception )
{ {
logger.LogError($"安装根证书{caPublicCerPath}失败:{ex.Message}"); logger.LogError($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
} }
} }
} }

View File

@ -37,7 +37,7 @@ namespace FastGithub
while (stoppingToken.IsCancellationRequested == false) while (stoppingToken.IsCancellationRequested == false)
{ {
await Task.Delay(this.options.CurrentValue.ResultScanInterval, stoppingToken); await Task.Delay(this.options.CurrentValue.ResultScanInterval, stoppingToken);
await githubScanService.ScanResultAsync(); await githubScanService.ScanResultAsync(stoppingToken);
} }
} }
} }

View File

@ -1,18 +1,68 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.Scanner namespace FastGithub.Scanner
{ {
/// <summary> /// <summary>
/// GithubContext集合 /// github扫描结果
/// </summary> /// </summary>
[Service(ServiceLifetime.Singleton)] [Service(ServiceLifetime.Singleton)]
sealed class GithubScanResults sealed class GithubScanResults
{ {
private const string dataFile = "FastGithub.dat";
private readonly object syncRoot = new(); private readonly object syncRoot = new();
private readonly List<GithubContext> contexts = new(); private readonly List<GithubContext> contexts = new();
private readonly ILogger<GithubScanResults> logger;
/// <summary>
/// github扫描结果
/// </summary>
/// <param name="logger"></param>
public GithubScanResults(ILogger<GithubScanResults> logger)
{
this.logger = logger;
var datas = LoadDatas(logger);
foreach (var context in datas)
{
this.Add(context);
}
}
/// <summary>
/// 从磁盘加载数据
/// </summary>
/// <param name="logger"></param>
/// <returns></returns>
private static GithubContext[] LoadDatas(ILogger logger)
{
try
{
if (File.Exists(dataFile) == true)
{
var json = File.ReadAllBytes(dataFile);
var datas = JsonSerializer.Deserialize<GithubDomainAddress[]>(json);
if (datas != null)
{
return datas.Select(item => item.ToGithubContext()).ToArray();
}
}
}
catch (Exception ex)
{
logger.LogWarning($"从{dataFile}加载数据失败:{ex.Message}");
}
return Array.Empty<GithubContext>();
}
/// <summary> /// <summary>
/// 添加GithubContext /// 添加GithubContext
@ -42,7 +92,7 @@ namespace FastGithub.Scanner
{ {
return this.contexts.ToArray(); return this.contexts.ToArray();
} }
} }
/// <summary> /// <summary>
/// 查找最优的ip /// 查找最优的ip
@ -50,11 +100,11 @@ namespace FastGithub.Scanner
/// <param name="domain"></param> /// <param name="domain"></param>
/// <returns></returns> /// <returns></returns>
public IPAddress? FindBestAddress(string domain) public IPAddress? FindBestAddress(string domain)
{ {
lock (this.syncRoot) lock (this.syncRoot)
{ {
return this.contexts return this.contexts
.Where(item => item.Domain == domain && item.AvailableRate > 0d) .Where(item => item.Domain == domain)
.OrderByDescending(item => item.AvailableRate) .OrderByDescending(item => item.AvailableRate)
.ThenByDescending(item => item.Available) .ThenByDescending(item => item.Available)
.ThenBy(item => item.AvgElapsed) .ThenBy(item => item.AvgElapsed)
@ -62,5 +112,54 @@ namespace FastGithub.Scanner
.FirstOrDefault(); .FirstOrDefault();
} }
} }
/// <summary>
/// 保存数据到磁盘
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task SaveDatasAsync(CancellationToken cancellationToken = default)
{
try
{
using var stream = File.OpenWrite(dataFile);
var datas = this.ToArray()
.OrderByDescending(item => item.AvailableRate)
.Select(item => GithubDomainAddress.From(item));
await JsonSerializer.SerializeAsync(stream, datas, cancellationToken: cancellationToken);
}
catch (Exception ex)
{
this.logger.LogWarning($"保存数据到{dataFile}失败:{ex.Message}");
}
}
/// <summary>
/// github的域名与ip关系数据
/// </summary>
private class GithubDomainAddress
{
[AllowNull]
public string Domain { get; set; }
[AllowNull]
public string Address { get; set; }
public GithubContext ToGithubContext()
{
return new GithubContext(this.Domain, IPAddress.Parse(this.Address)) { Available = true };
}
public static GithubDomainAddress From(GithubContext context)
{
return new GithubDomainAddress
{
Domain = context.Domain,
Address = context.Address.ToString()
};
}
}
} }
} }

View File

@ -133,10 +133,11 @@ namespace FastGithub.Scanner
} }
/// <summary> /// <summary>
/// 扫描曾经扫描到的结果 /// 扫描历史结果
/// </summary> /// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
public async Task ScanResultAsync() public async Task ScanResultAsync(CancellationToken cancellationToken)
{ {
this.logger.LogInformation("结果扫描开始.."); this.logger.LogInformation("结果扫描开始..");
@ -161,6 +162,7 @@ namespace FastGithub.Scanner
} }
this.dnsFlushService.FlushGithubResolverCache(); this.dnsFlushService.FlushGithubResolverCache();
this.logger.LogInformation($"结果扫描结束,共扫描{results.Length}条记录"); this.logger.LogInformation($"结果扫描结束,共扫描{results.Length}条记录");
await this.scanResults.SaveDatasAsync(cancellationToken);
} }
} }
} }

View File

@ -39,7 +39,7 @@ namespace FastGithub
return services return services
.AddMemoryCache() .AddMemoryCache()
.AddServiceAndOptions(assembly, configuration) .AddServiceAndOptions(assembly, configuration)
.AddHostedService<GithubFullScanHostedService>() //.AddHostedService<GithubFullScanHostedService>()
.AddHostedService<GithubResultScanHostedService>(); .AddHostedService<GithubResultScanHostedService>();
; ;
} }