ConnectionPool+Waiter.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright 2021, 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. import NIOCore
  17. import NIOHTTP2
  18. extension ConnectionPool {
  19. @usableFromInline
  20. internal final class Waiter {
  21. /// A promise to complete with the initialized channel.
  22. @usableFromInline
  23. internal let _promise: EventLoopPromise<Channel>
  24. @usableFromInline
  25. internal var _channelFuture: EventLoopFuture<Channel> {
  26. return self._promise.futureResult
  27. }
  28. /// The channel initializer.
  29. @usableFromInline
  30. internal let _channelInitializer: @Sendable (Channel) -> EventLoopFuture<Void>
  31. /// The deadline at which the timeout is scheduled.
  32. @usableFromInline
  33. internal let _deadline: NIODeadline
  34. /// A scheduled task which fails the stream promise should the pool not provide
  35. /// a stream in time.
  36. @usableFromInline
  37. internal var _scheduledTimeout: Scheduled<Void>?
  38. /// An identifier for this waiter.
  39. @usableFromInline
  40. internal var id: ID {
  41. return ID(self)
  42. }
  43. @usableFromInline
  44. internal init(
  45. deadline: NIODeadline,
  46. promise: EventLoopPromise<Channel>,
  47. channelInitializer: @escaping @Sendable (Channel) -> EventLoopFuture<Void>
  48. ) {
  49. self._deadline = deadline
  50. self._promise = promise
  51. self._channelInitializer = channelInitializer
  52. self._scheduledTimeout = nil
  53. }
  54. /// Schedule a timeout for this waiter. This task will be cancelled when the waiter is
  55. /// succeeded or failed.
  56. ///
  57. /// - Parameters:
  58. /// - eventLoop: The `EventLoop` to run the timeout task on.
  59. /// - body: The closure to execute when the timeout is fired.
  60. @usableFromInline
  61. internal func scheduleTimeout(
  62. on eventLoop: EventLoop,
  63. execute body: @escaping () -> Void
  64. ) {
  65. assert(self._scheduledTimeout == nil)
  66. self._scheduledTimeout = eventLoop.scheduleTask(deadline: self._deadline, body)
  67. }
  68. /// Returns a boolean value indicating whether the deadline for this waiter occurs after the
  69. /// given deadline.
  70. @usableFromInline
  71. internal func deadlineIsAfter(_ other: NIODeadline) -> Bool {
  72. return self._deadline > other
  73. }
  74. /// Succeed the waiter with the given multiplexer.
  75. @usableFromInline
  76. internal func succeed(with multiplexer: HTTP2StreamMultiplexer) {
  77. self._scheduledTimeout?.cancel()
  78. self._scheduledTimeout = nil
  79. multiplexer.createStreamChannel(promise: self._promise, self._channelInitializer)
  80. }
  81. /// Fail the waiter with `error`.
  82. @usableFromInline
  83. internal func fail(_ error: Error) {
  84. self._scheduledTimeout?.cancel()
  85. self._scheduledTimeout = nil
  86. self._promise.fail(error)
  87. }
  88. /// The ID of a waiter.
  89. @usableFromInline
  90. internal struct ID: Hashable, CustomStringConvertible {
  91. @usableFromInline
  92. internal let _id: ObjectIdentifier
  93. @usableFromInline
  94. internal init(_ waiter: Waiter) {
  95. self._id = ObjectIdentifier(waiter)
  96. }
  97. @usableFromInline
  98. internal var description: String {
  99. return String(describing: self._id)
  100. }
  101. }
  102. }
  103. }