GithubContextCollection.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using Microsoft.Extensions.DependencyInjection;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. namespace FastGithub.Scanner
  6. {
  7. [Service(ServiceLifetime.Singleton)]
  8. sealed class GithubContextCollection : IGithubScanResults
  9. {
  10. private readonly object syncRoot = new();
  11. private readonly List<GithubContext> contextList = new();
  12. public bool Add(GithubContext context)
  13. {
  14. lock (this.syncRoot)
  15. {
  16. if (this.contextList.Contains(context))
  17. {
  18. return false;
  19. }
  20. this.contextList.Add(context);
  21. return true;
  22. }
  23. }
  24. public GithubContext[] ToArray()
  25. {
  26. lock (this.syncRoot)
  27. {
  28. return this.contextList.ToArray();
  29. }
  30. }
  31. public bool IsAvailable(string domain, IPAddress address)
  32. {
  33. lock (this.syncRoot)
  34. {
  35. var target = new GithubContext(domain, address);
  36. var context = this.contextList.Find(item => item.Equals(target));
  37. return context != null && context.Available;
  38. }
  39. }
  40. /// <summary>
  41. /// 查找又稳又快的ip
  42. /// </summary>
  43. /// <param name="domain"></param>
  44. /// <returns></returns>
  45. public IPAddress? FindBestAddress(string domain)
  46. {
  47. lock (this.syncRoot)
  48. {
  49. return this.contextList
  50. .Where(item => item.Available && item.Domain == domain)
  51. .OrderByDescending(item => item.Statistics.GetSuccessRate())
  52. .ThenBy(item => item.Statistics.GetAvgElapsed())
  53. .Select(item => item.Address)
  54. .FirstOrDefault();
  55. }
  56. }
  57. }
  58. }