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);
        }
Example #2
0
        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);
        }