private static void InitializeUnsafeGrpcOptions(OperationContext context, GrpcEnvironmentOptions options) { if (options.ThreadPoolSize != null && options.ThreadPoolSize > 0) { Tracer.Info(context, $"Setting gRPC ThreadPoolSize to `{options.ThreadPoolSize.Value}`"); global::Grpc.Core.GrpcEnvironment.SetThreadPoolSize(options.ThreadPoolSize.Value); } if (options.CompletionQueueCount != null && options.CompletionQueueCount > 0) { Tracer.Info(context, $"Setting gRPC CompletionQueueCount to `{options.CompletionQueueCount.Value}`"); global::Grpc.Core.GrpcEnvironment.SetCompletionQueueCount(options.CompletionQueueCount.Value); } if (options.HandlerInlining ?? false) { Tracer.Info(context, $"Setting gRPC HandlerInlining to `{options.HandlerInlining.Value}`"); global::Grpc.Core.GrpcEnvironment.SetHandlerInlining(options.HandlerInlining.Value); } }
private static void InitializeCore(OperationContext context, ILogger?logger, GrpcEnvironmentOptions options, bool overwriteSafeOptions) { lock (InitializationLock) { if (InitializationCompletionSource.Task.IsFaulted) { AggregateException?exception = InitializationCompletionSource.Task.Exception; var innerException = exception?.InnerException; Contract.AssertNotNull(innerException); ExceptionDispatchInfo.Capture(innerException).Throw(); } if (IsInitialized) { Tracer.Info(context, "Attempt to initialize gRPC environment aborted due to a previous initialization."); if (overwriteSafeOptions) { InitializeSafeGrpcOptions(context, options, logger); } } else { // We don't retry if this errors because it likely means that something broke in gRPC core try { InitializeSafeGrpcOptions(context, options, logger); InitializeUnsafeGrpcOptions(context, options); } catch (Exception e) { InitializationCompletionSource.SetException(e); throw; } IsInitialized = true; InitializationCompletionSource.SetResult(1); } } }
private static void InitializeSafeGrpcOptions(OperationContext context, GrpcEnvironmentOptions options, ILogger?logger) { Contract.Requires(options.LoggingVerbosity == GrpcEnvironmentOptions.GrpcVerbosity.Disabled || logger != null, "Attempt to enable gRPC internal logging without a logger to forward logs to"); // Setting GRPC_DNS_RESOLVER=native to bypass ares DNS resolver which seems to cause // temporary long delays (2 minutes) while failing to resolve DNS using ares in some environments Environment.SetEnvironmentVariable("GRPC_DNS_RESOLVER", "native"); if (options.ExperimentalDisableFlowControl ?? false) { Tracer.Info(context, "Disabling gRPC flow control"); Environment.SetEnvironmentVariable("GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL", "1"); } if (options.ClientChannelBackupPollIntervalMs != null && options.ClientChannelBackupPollIntervalMs >= 0) { var value = options.ClientChannelBackupPollIntervalMs.Value.ToString(); Tracer.Info(context, $"Setting gRPC ClientChannelBackupPollIntervalMs to `{value}`"); Environment.SetEnvironmentVariable("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", value); } if (options.LoggingVerbosity != GrpcEnvironmentOptions.GrpcVerbosity.Disabled) { var verbosityValue = options.LoggingVerbosity.ToString("g").ToUpper(); string traceValue = "<EMPTY>"; Environment.SetEnvironmentVariable("GRPC_VERBOSITY", verbosityValue); if (options.Trace != null) { traceValue = string.Join(",", options.Trace); Environment.SetEnvironmentVariable("GRPC_TRACE", traceValue); } Tracer.Info(context, $"Initializing gRPC logger to verbosity `{verbosityValue}` with traces: {traceValue}"); global::Grpc.Core.GrpcEnvironment.SetLogger(new GrpcLoggerAdapter(context.TracingContext)); } }