HttpClientFactory.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using FastGithub.Configuration;
  2. using FastGithub.DomainResolve;
  3. using System;
  4. using System.Collections.Concurrent;
  5. namespace FastGithub.Http
  6. {
  7. /// <summary>
  8. /// HttpClient工厂
  9. /// </summary>
  10. sealed class HttpClientFactory : IHttpClientFactory
  11. {
  12. private readonly IDomainResolver domainResolver;
  13. /// <summary>
  14. /// 首次生命周期
  15. /// </summary>
  16. private readonly TimeSpan firstLiftTime = TimeSpan.FromSeconds(10d);
  17. /// <summary>
  18. /// 非首次生命周期
  19. /// </summary>
  20. private readonly TimeSpan nextLifeTime = TimeSpan.FromSeconds(100d);
  21. /// <summary>
  22. /// LifetimeHttpHandler清理器
  23. /// </summary>
  24. private readonly LifetimeHttpHandlerCleaner httpHandlerCleaner = new();
  25. /// <summary>
  26. /// LazyOf(LifetimeHttpHandler)缓存
  27. /// </summary>
  28. private readonly ConcurrentDictionary<LifeTimeKey, Lazy<LifetimeHttpHandler>> httpHandlerLazyCache = new();
  29. /// <summary>
  30. /// HttpClient工厂
  31. /// </summary>
  32. /// <param name="domainResolver"></param>
  33. public HttpClientFactory(IDomainResolver domainResolver)
  34. {
  35. this.domainResolver = domainResolver;
  36. }
  37. /// <summary>
  38. /// 创建httpClient
  39. /// </summary>
  40. /// <param name="domain"></param>
  41. /// <param name="domainConfig"></param>
  42. /// <returns></returns>
  43. public HttpClient CreateHttpClient(string domain, DomainConfig domainConfig)
  44. {
  45. var lifeTimeKey = new LifeTimeKey(domain, domainConfig);
  46. var lifetimeHttpHandler = this.httpHandlerLazyCache.GetOrAdd(lifeTimeKey, CreateLifetimeHttpHandlerLazy).Value;
  47. return new HttpClient(lifetimeHttpHandler, disposeHandler: false);
  48. Lazy<LifetimeHttpHandler> CreateLifetimeHttpHandlerLazy(LifeTimeKey lifeTimeKey)
  49. {
  50. return new Lazy<LifetimeHttpHandler>(() => this.CreateLifetimeHttpHandler(lifeTimeKey, this.firstLiftTime), true);
  51. }
  52. }
  53. /// <summary>
  54. /// 创建LifetimeHttpHandler
  55. /// </summary>
  56. /// <param name="lifeTimeKey"></param>
  57. /// <param name="lifeTime"></param>
  58. /// <returns></returns>
  59. private LifetimeHttpHandler CreateLifetimeHttpHandler(LifeTimeKey lifeTimeKey, TimeSpan lifeTime)
  60. {
  61. return new LifetimeHttpHandler(this.domainResolver, lifeTimeKey, lifeTime, this.OnLifetimeHttpHandlerDeactivate);
  62. }
  63. /// <summary>
  64. /// 当有httpHandler失效时
  65. /// </summary>
  66. /// <param name="lifetimeHttpHandler">httpHandler</param>
  67. private void OnLifetimeHttpHandlerDeactivate(LifetimeHttpHandler lifetimeHttpHandler)
  68. {
  69. var lifeTimeKey = lifetimeHttpHandler.LifeTimeKey;
  70. this.httpHandlerLazyCache[lifeTimeKey] = CreateLifetimeHttpHandlerLazy(lifeTimeKey);
  71. this.httpHandlerCleaner.Add(lifetimeHttpHandler);
  72. Lazy<LifetimeHttpHandler> CreateLifetimeHttpHandlerLazy(LifeTimeKey lifeTimeKey)
  73. {
  74. return new Lazy<LifetimeHttpHandler>(() => this.CreateLifetimeHttpHandler(lifeTimeKey, this.nextLifeTime), true);
  75. }
  76. }
  77. }
  78. }