1 #region Copyright notice and license 2 // Copyright 2015 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 #endregion 16 using System; 17 using System.Collections.Generic; 18 using System.Runtime.InteropServices; 19 using System.Threading; 20 using System.Threading.Tasks; 21 using Grpc.Core.Internal; 22 using Grpc.Core.Utils; 23 24 namespace Grpc.Core 25 { 26 /// <summary> 27 /// Channel option specified when creating a channel. 28 /// Corresponds to grpc_channel_args from grpc/grpc.h. 29 /// </summary> 30 public sealed class ChannelOption 31 { 32 /// <summary> 33 /// Type of <c>ChannelOption</c>. 34 /// </summary> 35 public enum OptionType 36 { 37 /// <summary> 38 /// Channel option with integer value. 39 /// </summary> 40 Integer, 41 42 /// <summary> 43 /// Channel option with string value. 44 /// </summary> 45 String 46 } 47 48 private readonly OptionType type; 49 private readonly string name; 50 private readonly int intValue; 51 private readonly string stringValue; 52 53 /// <summary> 54 /// Creates a channel option with a string value. 55 /// </summary> 56 /// <param name="name">Name.</param> 57 /// <param name="stringValue">String value.</param> ChannelOption(string name, string stringValue)58 public ChannelOption(string name, string stringValue) 59 { 60 this.type = OptionType.String; 61 this.name = GrpcPreconditions.CheckNotNull(name, "name"); 62 this.stringValue = GrpcPreconditions.CheckNotNull(stringValue, "stringValue"); 63 } 64 65 /// <summary> 66 /// Creates a channel option with an integer value. 67 /// </summary> 68 /// <param name="name">Name.</param> 69 /// <param name="intValue">Integer value.</param> ChannelOption(string name, int intValue)70 public ChannelOption(string name, int intValue) 71 { 72 this.type = OptionType.Integer; 73 this.name = GrpcPreconditions.CheckNotNull(name, "name"); 74 this.intValue = intValue; 75 } 76 77 /// <summary> 78 /// Gets the type of the <c>ChannelOption</c>. 79 /// </summary> 80 public OptionType Type 81 { 82 get 83 { 84 return type; 85 } 86 } 87 88 /// <summary> 89 /// Gets the name of the <c>ChannelOption</c>. 90 /// </summary> 91 public string Name 92 { 93 get 94 { 95 return name; 96 } 97 } 98 99 /// <summary> 100 /// Gets the integer value the <c>ChannelOption</c>. 101 /// </summary> 102 public int IntValue 103 { 104 get 105 { 106 GrpcPreconditions.CheckState(type == OptionType.Integer); 107 return intValue; 108 } 109 } 110 111 /// <summary> 112 /// Gets the string value the <c>ChannelOption</c>. 113 /// </summary> 114 public string StringValue 115 { 116 get 117 { 118 GrpcPreconditions.CheckState(type == OptionType.String); 119 return stringValue; 120 } 121 } 122 } 123 124 /// <summary> 125 /// Defines names of supported channel options. 126 /// </summary> 127 public static class ChannelOptions 128 { 129 /// <summary>Override SSL target check. Only to be used for testing.</summary> 130 public const string SslTargetNameOverride = "grpc.ssl_target_name_override"; 131 132 /// <summary>Enable census for tracing and stats collection</summary> 133 public const string Census = "grpc.census"; 134 135 /// <summary>Maximum number of concurrent incoming streams to allow on a http2 connection</summary> 136 public const string MaxConcurrentStreams = "grpc.max_concurrent_streams"; 137 138 /// <summary>Maximum message length that the channel can receive</summary> 139 public const string MaxReceiveMessageLength = "grpc.max_receive_message_length"; 140 141 /// <summary>Maximum message length that the channel can send</summary> 142 public const string MaxSendMessageLength = "grpc.max_send_message_length"; 143 144 /// <summary>Obsolete, for backward compatibility only.</summary> 145 [Obsolete("Use MaxReceiveMessageLength instead.")] 146 public const string MaxMessageLength = MaxReceiveMessageLength; 147 148 /// <summary>Initial sequence number for http2 transports</summary> 149 public const string Http2InitialSequenceNumber = "grpc.http2.initial_sequence_number"; 150 151 /// <summary>Default authority for calls.</summary> 152 public const string DefaultAuthority = "grpc.default_authority"; 153 154 /// <summary>Primary user agent: goes at the start of the user-agent metadata</summary> 155 public const string PrimaryUserAgentString = "grpc.primary_user_agent"; 156 157 /// <summary>Secondary user agent: goes at the end of the user-agent metadata</summary> 158 public const string SecondaryUserAgentString = "grpc.secondary_user_agent"; 159 160 /// <summary>If non-zero, allow the use of SO_REUSEPORT for server if it's available (default 1)</summary> 161 public const string SoReuseport = "grpc.so_reuseport"; 162 163 /// <summary> 164 /// Creates native object for a collection of channel options. 165 /// </summary> 166 /// <returns>The native channel arguments.</returns> CreateChannelArgs(ICollection<ChannelOption> options)167 internal static ChannelArgsSafeHandle CreateChannelArgs(ICollection<ChannelOption> options) 168 { 169 if (options == null || options.Count == 0) 170 { 171 return ChannelArgsSafeHandle.CreateNull(); 172 } 173 ChannelArgsSafeHandle nativeArgs = null; 174 try 175 { 176 nativeArgs = ChannelArgsSafeHandle.Create(options.Count); 177 int i = 0; 178 foreach (var option in options) 179 { 180 if (option.Type == ChannelOption.OptionType.Integer) 181 { 182 nativeArgs.SetInteger(i, option.Name, option.IntValue); 183 } 184 else if (option.Type == ChannelOption.OptionType.String) 185 { 186 nativeArgs.SetString(i, option.Name, option.StringValue); 187 } 188 else 189 { 190 throw new InvalidOperationException("Unknown option type"); 191 } 192 i++; 193 } 194 return nativeArgs; 195 } 196 catch (Exception) 197 { 198 if (nativeArgs != null) 199 { 200 nativeArgs.Dispose(); 201 } 202 throw; 203 } 204 } 205 } 206 } 207