ChannelArgument.swift 7.9 KB

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