| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import Foundation
- import NIO
- public enum GRPCTimeoutError: String, Error {
- case negative = "GRPCTimeout must be non-negative"
- case tooManyDigits = "GRPCTimeout must be at most 8 digits"
- }
- /// A timeout for a gRPC call.
- ///
- /// Timeouts must be positive and at most 8-digits long.
- public struct GRPCTimeout: CustomStringConvertible, Equatable {
- public static let `default`: GRPCTimeout = try! .minutes(1)
- /// Creates an infinite timeout. This is a sentinel value which must __not__ be sent to a gRPC service.
- public static let infinite: GRPCTimeout = GRPCTimeout(nanoseconds: Int64.max, description: "infinite")
- /// A description of the timeout in the format described in the
- /// [gRPC protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md).
- public let description: String
- public let nanoseconds: Int64
- private init(nanoseconds: Int64, description: String) {
- self.nanoseconds = nanoseconds
- self.description = description
- }
- private static func makeTimeout(_ amount: Int, _ unit: GRPCTimeoutUnit) throws -> GRPCTimeout {
- // Timeouts must be positive and at most 8-digits.
- if amount < 0 { throw GRPCTimeoutError.negative }
- if amount >= 100_000_000 { throw GRPCTimeoutError.tooManyDigits }
- // See "Timeout" in https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
- let description = "\(amount)\(unit.rawValue)"
- let nanoseconds = Int64(amount) * Int64(unit.asNanoseconds)
- return GRPCTimeout(nanoseconds: nanoseconds, description: description)
- }
- /// Creates a new GRPCTimeout for the given amount of hours.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of hours this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of hours.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func hours(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .hours)
- }
- /// Creates a new GRPCTimeout for the given amount of minutes.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of minutes this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of minutes.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func minutes(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .minutes)
- }
- /// Creates a new GRPCTimeout for the given amount of seconds.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of seconds this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of seconds.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func seconds(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .seconds)
- }
- /// Creates a new GRPCTimeout for the given amount of milliseconds.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of milliseconds this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of milliseconds.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func milliseconds(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .milliseconds)
- }
- /// Creates a new GRPCTimeout for the given amount of microseconds.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of microseconds this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of microseconds.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func microseconds(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .microseconds)
- }
- /// Creates a new GRPCTimeout for the given amount of nanoseconds.
- ///
- /// `amount` must be positive and at most 8-digits.
- ///
- /// - Parameter amount: the amount of nanoseconds this `GRPCTimeout` represents.
- /// - Returns: A `GRPCTimeout` representing the given number of nanoseconds.
- /// - Throws: `GRPCTimeoutError` if the amount was negative or more than 8 digits long.
- public static func nanoseconds(_ amount: Int) throws -> GRPCTimeout {
- return try makeTimeout(amount, .nanoseconds)
- }
- }
- extension GRPCTimeout {
- /// Returns a NIO `TimeAmount` representing the amount of time as this timeout.
- public var asNIOTimeAmount: TimeAmount {
- return TimeAmount.nanoseconds(numericCast(nanoseconds))
- }
- }
- private enum GRPCTimeoutUnit: String {
- case hours = "H"
- case minutes = "M"
- case seconds = "S"
- case milliseconds = "m"
- case microseconds = "u"
- case nanoseconds = "n"
- internal var asNanoseconds: Int {
- switch self {
- case .hours:
- return 60 * 60 * 1000 * 1000 * 1000
- case .minutes:
- return 60 * 1000 * 1000 * 1000
- case .seconds:
- return 1000 * 1000 * 1000
- case .milliseconds:
- return 1000 * 1000
- case .microseconds:
- return 1000
- case .nanoseconds:
- return 1
- }
- }
- }
|