예제 #1
0
        internal ConnectionManager(
            Resolver resolver,
            bool disableResolverServiceConfig,
            ILoggerFactory loggerFactory,
            ISubchannelTransportFactory subchannelTransportFactory,
            LoadBalancerFactory[] loadBalancerFactories)
        {
            _lock               = new object();
            _nextPickerLock     = new SemaphoreSlim(1);
            _nextPickerTcs      = new TaskCompletionSource <SubchannelPicker>(TaskCreationOptions.RunContinuationsAsynchronously);
            _resolverStartedTcs = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously);

            Logger        = loggerFactory.CreateLogger <ConnectionManager>();
            LoggerFactory = loggerFactory;

            _subchannels   = new List <Subchannel>();
            _stateWatchers = new List <StateWatcher>();
            _resolver      = resolver;
            DisableResolverServiceConfig = disableResolverServiceConfig;
            _subchannelTransportFactory  = subchannelTransportFactory;
            LoadBalancerFactories        = loadBalancerFactories;
        }
예제 #2
0
        internal GrpcChannel(Uri address, GrpcChannelOptions channelOptions) : base(address.Authority)
        {
            _lock            = new object();
            _methodInfoCache = new ConcurrentDictionary <IMethod, GrpcMethodInfo>();

            // Dispose the HTTP client/handler if...
            //   1. No client/handler was specified and so the channel created the client itself
            //   2. User has specified a client/handler and set DisposeHttpClient to true
            _shouldDisposeHttpClient = (channelOptions.HttpClient == null && channelOptions.HttpHandler == null) ||
                                       channelOptions.DisposeHttpClient;

            Address         = address;
            LoggerFactory   = channelOptions.LoggerFactory ?? ResolveService <ILoggerFactory>(channelOptions.ServiceProvider, NullLoggerFactory.Instance);
            RandomGenerator = ResolveService <IRandomGenerator>(channelOptions.ServiceProvider, new RandomGenerator());
            HttpHandlerType = CalculateHandlerType(channelOptions);

#if SUPPORT_LOAD_BALANCING
            var resolverFactory = GetResolverFactory(channelOptions);
            ResolveCredentials(channelOptions, out _isSecure, out _callCredentials);

            SubchannelTransportFactory = ResolveService <ISubchannelTransportFactory>(channelOptions.ServiceProvider, new SubChannelTransportFactory(this));

            if (!IsHttpOrHttpsAddress() || channelOptions.ServiceConfig?.LoadBalancingConfigs.Count > 0)
            {
                ValidateHttpHandlerSupportsConnectivity();
            }

            var defaultPort = IsSecure ? 443 : 80;
            var resolver    = resolverFactory.Create(new ResolverOptions(Address, defaultPort, channelOptions.DisableResolverServiceConfig, LoggerFactory));

            ConnectionManager = new ConnectionManager(
                resolver,
                channelOptions.DisableResolverServiceConfig,
                LoggerFactory,
                SubchannelTransportFactory,
                ResolveLoadBalancerFactories(channelOptions.ServiceProvider));
            ConnectionManager.ConfigureBalancer(c => new ChildHandlerLoadBalancer(
                                                    c,
                                                    channelOptions.ServiceConfig,
                                                    ConnectionManager));
#else
            if (string.IsNullOrEmpty(address.Host))
            {
                throw new ArgumentException($"Address '{address.OriginalString}' doesn't have a host. Address should include a scheme, host, and optional port. For example, 'https://localhost:5001'.");
            }
            ResolveCredentials(channelOptions, out _isSecure, out _callCredentials);
#endif

            HttpInvoker               = channelOptions.HttpClient ?? CreateInternalHttpInvoker(channelOptions.HttpHandler);
            SendMaxMessageSize        = channelOptions.MaxSendMessageSize;
            ReceiveMaxMessageSize     = channelOptions.MaxReceiveMessageSize;
            MaxRetryAttempts          = channelOptions.MaxRetryAttempts;
            MaxRetryBufferSize        = channelOptions.MaxRetryBufferSize;
            MaxRetryBufferPerCallSize = channelOptions.MaxRetryBufferPerCallSize;
            CompressionProviders      = ResolveCompressionProviders(channelOptions.CompressionProviders);
            MessageAcceptEncoding     = GrpcProtocolHelpers.GetMessageAcceptEncoding(CompressionProviders);
            Logger = LoggerFactory.CreateLogger <GrpcChannel>();
            ThrowOperationCanceledOnCancellation = channelOptions.ThrowOperationCanceledOnCancellation;
            _createMethodInfoFunc = CreateMethodInfo;
            ActiveCalls           = new HashSet <IDisposable>();
            if (channelOptions.ServiceConfig is { } serviceConfig)
            {
                RetryThrottling = serviceConfig.RetryThrottling != null?CreateChannelRetryThrottling(serviceConfig.RetryThrottling) : null;

                _serviceConfigMethods = CreateServiceConfigMethods(serviceConfig);
            }

            // Non-HTTP addresses (e.g. dns:///custom-hostname) usually specify a path instead of an authority.
            // Only log about a path being present if HTTP or HTTPS.
            if (!string.IsNullOrEmpty(Address.PathAndQuery) &&
                Address.PathAndQuery != "/" &&
                (Address.Scheme == Uri.UriSchemeHttps || Address.Scheme == Uri.UriSchemeHttp))
            {
                Log.AddressPathUnused(Logger, Address.OriginalString);
            }
        }