2
0

GithubScanService.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Microsoft.Extensions.DependencyInjection;
  2. using Microsoft.Extensions.Logging;
  3. using System;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. namespace FastGithub.Scanner
  9. {
  10. [Service(ServiceLifetime.Singleton, ServiceType = typeof(IGithubScanService))]
  11. sealed class GithubScanService : IGithubScanService
  12. {
  13. private readonly GithubMetaService metaService;
  14. private readonly GithubScanDelegate scanDelegate;
  15. private readonly ILogger<GithubScanService> logger;
  16. private readonly GithubContextHashSet results = new();
  17. public GithubScanService(
  18. GithubMetaService metaService,
  19. GithubScanDelegate scanDelegate,
  20. ILogger<GithubScanService> logger)
  21. {
  22. this.metaService = metaService;
  23. this.scanDelegate = scanDelegate;
  24. this.logger = logger;
  25. }
  26. public async Task ScanAllAsync(CancellationToken cancellationToken = default)
  27. {
  28. this.logger.LogInformation("完整扫描开始");
  29. var meta = await this.metaService.GetMetaAsync(cancellationToken);
  30. if (meta != null)
  31. {
  32. var scanTasks = meta.ToGithubContexts().Select(ctx => ScanAsync(ctx));
  33. await Task.WhenAll(scanTasks);
  34. }
  35. this.logger.LogInformation("完整扫描结束");
  36. async Task ScanAsync(GithubContext context)
  37. {
  38. await this.scanDelegate(context);
  39. if (context.HttpElapsed != null)
  40. {
  41. lock (this.results.SyncRoot)
  42. {
  43. this.results.Add(context);
  44. }
  45. }
  46. }
  47. }
  48. public async Task ScanResultAsync()
  49. {
  50. this.logger.LogInformation("结果扫描开始");
  51. GithubContext[] contexts;
  52. lock (this.results.SyncRoot)
  53. {
  54. contexts = this.results.ToArray();
  55. }
  56. foreach (var context in contexts)
  57. {
  58. context.HttpElapsed = null;
  59. await this.scanDelegate(context);
  60. }
  61. this.logger.LogInformation("结果扫描结束");
  62. }
  63. public IPAddress? FindFastAddress(string domain)
  64. {
  65. if (domain.Contains("github", StringComparison.OrdinalIgnoreCase))
  66. {
  67. return default;
  68. }
  69. lock (this.results.SyncRoot)
  70. {
  71. return this.results
  72. .Where(item => item.Domain == domain && item.HttpElapsed != null)
  73. .OrderBy(item => item.HttpElapsed)
  74. .Select(item => item.Address)
  75. .FirstOrDefault();
  76. }
  77. }
  78. }
  79. }