using FastGithub.Configuration; using FastGithub.DomainResolve; using System; using System.Collections.Concurrent; namespace FastGithub.Http { /// /// HttpClient工厂 /// sealed class HttpClientFactory : IHttpClientFactory { private readonly IDomainResolver domainResolver; /// /// 首次生命周期 /// private readonly TimeSpan firstLiftTime = TimeSpan.FromSeconds(10d); /// /// 非首次生命周期 /// private readonly TimeSpan nextLifeTime = TimeSpan.FromSeconds(100d); /// /// LifetimeHttpHandler清理器 /// private readonly LifetimeHttpHandlerCleaner httpHandlerCleaner = new(); /// /// LazyOf(LifetimeHttpHandler)缓存 /// private readonly ConcurrentDictionary> httpHandlerLazyCache = new(); /// /// HttpClient工厂 /// /// public HttpClientFactory(IDomainResolver domainResolver) { this.domainResolver = domainResolver; } /// /// 创建httpClient /// /// /// /// public HttpClient CreateHttpClient(string domain, DomainConfig domainConfig) { var lifeTimeKey = new LifeTimeKey(domain, domainConfig); var lifetimeHttpHandler = this.httpHandlerLazyCache.GetOrAdd(lifeTimeKey, CreateLifetimeHttpHandlerLazy).Value; return new HttpClient(lifetimeHttpHandler, disposeHandler: false); Lazy CreateLifetimeHttpHandlerLazy(LifeTimeKey lifeTimeKey) { return new Lazy(() => this.CreateLifetimeHttpHandler(lifeTimeKey, this.firstLiftTime), true); } } /// /// 创建LifetimeHttpHandler /// /// /// /// private LifetimeHttpHandler CreateLifetimeHttpHandler(LifeTimeKey lifeTimeKey, TimeSpan lifeTime) { return new LifetimeHttpHandler(this.domainResolver, lifeTimeKey, lifeTime, this.OnLifetimeHttpHandlerDeactivate); } /// /// 当有httpHandler失效时 /// /// httpHandler private void OnLifetimeHttpHandlerDeactivate(LifetimeHttpHandler lifetimeHttpHandler) { var lifeTimeKey = lifetimeHttpHandler.LifeTimeKey; this.httpHandlerLazyCache[lifeTimeKey] = CreateLifetimeHttpHandlerLazy(lifeTimeKey); this.httpHandlerCleaner.Add(lifetimeHttpHandler); Lazy CreateLifetimeHttpHandlerLazy(LifeTimeKey lifeTimeKey) { return new Lazy(() => this.CreateLifetimeHttpHandler(lifeTimeKey, this.nextLifeTime), true); } } } }