ChannelArgument.swift 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright 2018, gRPC Authors All rights reserved.
  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. */
  16. #if SWIFT_PACKAGE
  17. import CgRPC
  18. #endif
  19. import Foundation // for String.Encoding
  20. public extension Channel {
  21. enum Argument {
  22. /// Default authority to pass if none specified on call construction.
  23. case defaultAuthority(String)
  24. /// Primary user agent. Goes at the start of the user-agent metadata sent
  25. /// on each request.
  26. case primaryUserAgent(String)
  27. /// Secondary user agent. Goes at the end of the user-agent metadata sent
  28. /// on each request.
  29. case secondaryUserAgent(String)
  30. /// After a duration of this time, the client/server pings its peer to see
  31. /// if the transport is still alive.
  32. case keepAliveTime(TimeInterval)
  33. /// After waiting for a duration of this time, if the keepalive ping sender does
  34. /// not receive the ping ack, it will close the transport.
  35. case keepAliveTimeout(TimeInterval)
  36. /// Is it permissible to send keepalive pings without any outstanding streams?
  37. case keepAlivePermitWithoutCalls(Bool)
  38. /// The time between the first and second connection attempts.
  39. case reconnectBackoffInitial(TimeInterval)
  40. /// The minimum time between subsequent connection attempts.
  41. case reconnectBackoffMin(TimeInterval)
  42. /// The maximum time between subsequent connection attempts.
  43. case reconnectBackoffMax(TimeInterval)
  44. /// Should we allow receipt of true-binary data on http2 connections?
  45. /// Defaults to on (true)
  46. case http2EnableTrueBinary(Bool)
  47. /// Minimum time between sending successive ping frames without receiving
  48. /// any data frame.
  49. case http2MinSentPingInterval(TimeInterval)
  50. /// Number of pings before needing to send a data frame or header frame.
  51. /// `0` indicates that an infinite number of pings can be sent without
  52. /// sending a data frame or header frame.
  53. case http2MaxPingsWithoutData(UInt)
  54. /// This *should* be used for testing only.
  55. /// Override the target name used for SSL host name checking using this
  56. /// channel argument. If this argument is not specified, the name used
  57. /// for SSL host name checking will be the target parameter (assuming that the
  58. /// secure channel is an SSL channel). If this parameter is specified and the
  59. /// underlying is not an SSL channel, it will just be ignored.
  60. case sslTargetNameOverride(String)
  61. /// Enable census for tracing and stats collection.
  62. case enableCensus(Bool)
  63. /// Enable load reporting.
  64. case enableLoadReporting(Bool)
  65. /// Request that optional features default to off (regarless of what they usually
  66. /// default to) - to enable tight control over what gets enabled.
  67. case enableMinimalStack(Bool)
  68. /// Maximum number of concurrent incoming streams to allow on a http2 connection.
  69. case maxConcurrentStreams(UInt)
  70. /// Maximum message length that the channel can receive (in byts).
  71. /// -1 means unlimited.
  72. case maxReceiveMessageLength(Int)
  73. /// Maximum message length that the channel can send (in bytes).
  74. /// -1 means unlimited.
  75. case maxSendMessageLength(Int)
  76. /// Maximum time that a channel may have no outstanding rpcs.
  77. case maxConnectionIdle(TimeInterval)
  78. /// Maximum time that a channel may exist.
  79. case maxConnectionAge(TimeInterval)
  80. /// Enable/disable support for deadline checking.
  81. /// Defaults to true, unless `enableMinimalStack` is enabled, in which case it
  82. /// defaults to false.
  83. case enableDeadlineChecks(Bool)
  84. }
  85. }
  86. extension Channel.Argument {
  87. class Wrapper {
  88. // Creating a `grpc_arg` allocates memory. This wrapper ensures that the memory is freed after use.
  89. let wrapped: grpc_arg
  90. init(_ wrapped: grpc_arg) {
  91. self.wrapped = wrapped
  92. }
  93. deinit {
  94. gpr_free(wrapped.key)
  95. if wrapped.type == GRPC_ARG_STRING {
  96. gpr_free(wrapped.value.string)
  97. }
  98. }
  99. }
  100. func toCArg() -> Wrapper {
  101. switch self {
  102. case let .defaultAuthority(value):
  103. return makeArgument("grpc.default_authority", value: value)
  104. case let .primaryUserAgent(value):
  105. return makeArgument("grpc.primary_user_agent", value: value)
  106. case let .secondaryUserAgent(value):
  107. return makeArgument("grpc.secondary_user_agent", value: value)
  108. case let .keepAliveTime(value):
  109. return makeArgument("grpc.keepalive_time_ms", value: value * 1_000)
  110. case let .keepAliveTimeout(value):
  111. return makeArgument("grpc.keepalive_timeout_ms", value: value * 1_000)
  112. case let .keepAlivePermitWithoutCalls(value):
  113. return makeArgument("grpc.keepalive_permit_without_calls", value: value)
  114. case let .reconnectBackoffMin(value):
  115. return makeArgument("grpc.min_reconnect_backoff_ms", value: value * 1_000)
  116. case let .reconnectBackoffMax(value):
  117. return makeArgument("grpc.max_reconnect_backoff_ms", value: value * 1_000)
  118. case let .reconnectBackoffInitial(value):
  119. return makeArgument("grpc.initial_reconnect_backoff_ms", value: value * 1_000)
  120. case let .http2EnableTrueBinary(value):
  121. return makeArgument("grpc.http2.true_binary", value: value)
  122. case let .http2MinSentPingInterval(value):
  123. return makeArgument("grpc.http2.min_time_between_pings_ms", value: value * 1_000)
  124. case let .http2MaxPingsWithoutData(value):
  125. return makeArgument("grpc.http2.max_pings_without_data", value: value)
  126. case let .sslTargetNameOverride(value):
  127. return makeArgument("grpc.ssl_target_name_override", value: value)
  128. case let .enableCensus(value):
  129. return makeArgument("grpc.census", value: value)
  130. case let .enableLoadReporting(value):
  131. return makeArgument("grpc.loadreporting", value: value)
  132. case let .enableMinimalStack(value):
  133. return makeArgument("grpc.minimal_stack", value: value)
  134. case let .maxConcurrentStreams(value):
  135. return makeArgument("grpc.max_concurrent_streams", value: value)
  136. case let .maxReceiveMessageLength(value):
  137. return makeArgument("grpc.max_receive_message_length", value: value)
  138. case let .maxSendMessageLength(value):
  139. return makeArgument("grpc.max_send_message_length", value: value)
  140. case let .maxConnectionIdle(value):
  141. return makeArgument("grpc.max_connection_idle_ms", value: value * 1_000)
  142. case let .maxConnectionAge(value):
  143. return makeArgument("grpc.max_connection_age_ms", value: value * 1_000)
  144. case let .enableDeadlineChecks(value):
  145. return makeArgument("grpc.enable_deadline_checking", value: value)
  146. }
  147. }
  148. }
  149. private func makeArgument(_ key: String, value: String) -> Channel.Argument.Wrapper {
  150. var arg = grpc_arg()
  151. arg.key = gpr_strdup(key)
  152. arg.type = GRPC_ARG_STRING
  153. arg.value.string = gpr_strdup(value)
  154. return Channel.Argument.Wrapper(arg)
  155. }
  156. private func makeArgument(_ key: String, value: Bool) -> Channel.Argument.Wrapper {
  157. return makeArgument(key, value: Int32(value ? 1 : 0))
  158. }
  159. private func makeArgument(_ key: String, value: Double) -> Channel.Argument.Wrapper {
  160. return makeArgument(key, value: Int32(value))
  161. }
  162. private func makeArgument(_ key: String, value: UInt) -> Channel.Argument.Wrapper {
  163. return makeArgument(key, value: Int32(value))
  164. }
  165. private func makeArgument(_ key: String, value: Int) -> Channel.Argument.Wrapper {
  166. return makeArgument(key, value: Int32(value))
  167. }
  168. private func makeArgument(_ key: String, value: Int32) -> Channel.Argument.Wrapper {
  169. var arg = grpc_arg()
  170. arg.key = gpr_strdup(key)
  171. arg.type = GRPC_ARG_INTEGER
  172. arg.value.integer = value
  173. return Channel.Argument.Wrapper(arg)
  174. }