private EndpointCache GetOrAddEndpoint(Uri endpoint) { // The GetorAdd is followed by a call to .Count which in a ConcurrentDictionary // will acquire all locks for all buckets. This is really expensive. Since the check // there is only to see if we've exceeded the count of endpoints, we can simply // avoid that check altogether if we are not adding any more endpoints. if (this.addressCacheByEndpoint.TryGetValue(endpoint, out EndpointCache existingCache)) { return(existingCache); } EndpointCache endpointCache = this.addressCacheByEndpoint.GetOrAdd( endpoint, (Uri resolvedEndpoint) => { GatewayAddressCache gatewayAddressCache = new GatewayAddressCache( resolvedEndpoint, this.protocol, this.tokenProvider, this.serviceConfigReader, this.httpClient, enableTcpConnectionEndpointRediscovery: this.enableTcpConnectionEndpointRediscovery); string location = this.endpointManager.GetLocation(endpoint); AddressResolver addressResolver = new AddressResolver(null, new NullRequestSigner(), location); addressResolver.InitializeCaches(this.collectionCache, this.routingMapProvider, gatewayAddressCache); return(new EndpointCache() { AddressCache = gatewayAddressCache, AddressResolver = addressResolver, }); }); if (this.addressCacheByEndpoint.Count > this.maxEndpoints) { IEnumerable <Uri> allEndpoints = this.endpointManager.WriteEndpoints.Union(this.endpointManager.ReadEndpoints); Queue <Uri> endpoints = new Queue <Uri>(allEndpoints.Reverse()); while (this.addressCacheByEndpoint.Count > this.maxEndpoints) { if (endpoints.Count > 0) { EndpointCache removedEntry; this.addressCacheByEndpoint.TryRemove(endpoints.Dequeue(), out removedEntry); } else { break; } } } return(endpointCache); }
private EndpointCache GetOrAddEndpoint(Uri endpoint) { EndpointCache endpointCache = this.addressCacheByEndpoint.GetOrAdd( endpoint, (Uri resolvedEndpoint) => { GatewayAddressCache gatewayAddressCache = new GatewayAddressCache( resolvedEndpoint, this.protocol, this.tokenProvider, this.userAgentContainer, this.serviceConfigReader, this.requestTimeout, messageHandler: this.messageHandler, apiType: this.apiType, enableTcpConnectionEndpointRediscovery: this.enableTcpConnectionEndpointRediscovery); string location = this.endpointManager.GetLocation(endpoint); AddressResolver addressResolver = new AddressResolver(null, new NullRequestSigner(), location); addressResolver.InitializeCaches(this.collectionCache, this.routingMapProvider, gatewayAddressCache); return(new EndpointCache() { AddressCache = gatewayAddressCache, AddressResolver = addressResolver, }); }); if (this.addressCacheByEndpoint.Count > this.maxEndpoints) { IEnumerable <Uri> allEndpoints = this.endpointManager.WriteEndpoints.Union(this.endpointManager.ReadEndpoints); Queue <Uri> endpoints = new Queue <Uri>(allEndpoints.Reverse()); while (this.addressCacheByEndpoint.Count > this.maxEndpoints) { if (endpoints.Count > 0) { EndpointCache removedEntry; this.addressCacheByEndpoint.TryRemove(endpoints.Dequeue(), out removedEntry); } else { break; } } } return(endpointCache); }