ServerHandlerStateMachine.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * Copyright 2022, 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 compiler(>=5.6)
  17. import NIOHPACK
  18. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  19. @usableFromInline
  20. internal struct ServerHandlerStateMachine {
  21. @usableFromInline
  22. internal private(set) var state: Self.State
  23. @inlinable
  24. init() {
  25. self.state = .idle(.init())
  26. }
  27. @inlinable
  28. mutating func setResponseHeaders(_ headers: HPACKHeaders) {
  29. switch self.state {
  30. case var .handling(handling):
  31. let nextStateAndOutput = handling.setResponseHeaders(headers)
  32. self.state = nextStateAndOutput.nextState.state
  33. return nextStateAndOutput.output
  34. case var .draining(draining):
  35. let nextStateAndOutput = draining.setResponseHeaders(headers)
  36. self.state = nextStateAndOutput.nextState.state
  37. return nextStateAndOutput.output
  38. case var .finished(finished):
  39. let nextStateAndOutput = finished.setResponseHeaders(headers)
  40. self.state = nextStateAndOutput.nextState.state
  41. return nextStateAndOutput.output
  42. case .idle:
  43. preconditionFailure()
  44. }
  45. }
  46. @inlinable
  47. mutating func setResponseTrailers(_ trailers: HPACKHeaders) {
  48. switch self.state {
  49. case var .handling(handling):
  50. let nextStateAndOutput = handling.setResponseTrailers(trailers)
  51. self.state = nextStateAndOutput.nextState.state
  52. return nextStateAndOutput.output
  53. case var .draining(draining):
  54. let nextStateAndOutput = draining.setResponseTrailers(trailers)
  55. self.state = nextStateAndOutput.nextState.state
  56. return nextStateAndOutput.output
  57. case var .finished(finished):
  58. let nextStateAndOutput = finished.setResponseTrailers(trailers)
  59. self.state = nextStateAndOutput.nextState.state
  60. return nextStateAndOutput.output
  61. case .idle:
  62. preconditionFailure()
  63. }
  64. }
  65. @inlinable
  66. mutating func handleMetadata() -> HandleMetadataAction {
  67. switch self.state {
  68. case var .idle(idle):
  69. let nextStateAndOutput = idle.handleMetadata()
  70. self.state = nextStateAndOutput.nextState.state
  71. return nextStateAndOutput.output
  72. case var .handling(handling):
  73. let nextStateAndOutput = handling.handleMetadata()
  74. self.state = nextStateAndOutput.nextState.state
  75. return nextStateAndOutput.output
  76. case var .draining(draining):
  77. let nextStateAndOutput = draining.handleMetadata()
  78. self.state = nextStateAndOutput.nextState.state
  79. return nextStateAndOutput.output
  80. case var .finished(finished):
  81. let nextStateAndOutput = finished.handleMetadata()
  82. self.state = nextStateAndOutput.nextState.state
  83. return nextStateAndOutput.output
  84. }
  85. }
  86. @inlinable
  87. mutating func handleMessage() -> HandleMessageAction {
  88. switch self.state {
  89. case var .idle(idle):
  90. let nextStateAndOutput = idle.handleMessage()
  91. self.state = nextStateAndOutput.nextState.state
  92. return nextStateAndOutput.output
  93. case var .handling(handling):
  94. let nextStateAndOutput = handling.handleMessage()
  95. self.state = nextStateAndOutput.nextState.state
  96. return nextStateAndOutput.output
  97. case var .draining(draining):
  98. let nextStateAndOutput = draining.handleMessage()
  99. self.state = nextStateAndOutput.nextState.state
  100. return nextStateAndOutput.output
  101. case var .finished(finished):
  102. let nextStateAndOutput = finished.handleMessage()
  103. self.state = nextStateAndOutput.nextState.state
  104. return nextStateAndOutput.output
  105. }
  106. }
  107. @inlinable
  108. mutating func handleEnd() -> HandleEndAction {
  109. switch self.state {
  110. case var .idle(idle):
  111. let nextStateAndOutput = idle.handleEnd()
  112. self.state = nextStateAndOutput.nextState.state
  113. return nextStateAndOutput.output
  114. case var .handling(handling):
  115. let nextStateAndOutput = handling.handleEnd()
  116. self.state = nextStateAndOutput.nextState.state
  117. return nextStateAndOutput.output
  118. case var .draining(draining):
  119. let nextStateAndOutput = draining.handleEnd()
  120. self.state = nextStateAndOutput.nextState.state
  121. return nextStateAndOutput.output
  122. case var .finished(finished):
  123. let nextStateAndOutput = finished.handleEnd()
  124. self.state = nextStateAndOutput.nextState.state
  125. return nextStateAndOutput.output
  126. }
  127. }
  128. @inlinable
  129. mutating func sendMessage() -> SendMessageAction {
  130. switch self.state {
  131. case var .handling(handling):
  132. let nextStateAndOutput = handling.sendMessage()
  133. self.state = nextStateAndOutput.nextState.state
  134. return nextStateAndOutput.output
  135. case var .draining(draining):
  136. let nextStateAndOutput = draining.sendMessage()
  137. self.state = nextStateAndOutput.nextState.state
  138. return nextStateAndOutput.output
  139. case var .finished(finished):
  140. let nextStateAndOutput = finished.sendMessage()
  141. self.state = nextStateAndOutput.nextState.state
  142. return nextStateAndOutput.output
  143. case .idle:
  144. preconditionFailure()
  145. }
  146. }
  147. @inlinable
  148. mutating func sendStatus() -> SendStatusAction {
  149. switch self.state {
  150. case var .handling(handling):
  151. let nextStateAndOutput = handling.sendStatus()
  152. self.state = nextStateAndOutput.nextState.state
  153. return nextStateAndOutput.output
  154. case var .draining(draining):
  155. let nextStateAndOutput = draining.sendStatus()
  156. self.state = nextStateAndOutput.nextState.state
  157. return nextStateAndOutput.output
  158. case var .finished(finished):
  159. let nextStateAndOutput = finished.sendStatus()
  160. self.state = nextStateAndOutput.nextState.state
  161. return nextStateAndOutput.output
  162. case .idle:
  163. preconditionFailure()
  164. }
  165. }
  166. @inlinable
  167. mutating func cancel() -> CancelAction {
  168. switch self.state {
  169. case var .idle(idle):
  170. let nextStateAndOutput = idle.cancel()
  171. self.state = nextStateAndOutput.nextState.state
  172. return nextStateAndOutput.output
  173. case var .handling(handling):
  174. let nextStateAndOutput = handling.cancel()
  175. self.state = nextStateAndOutput.nextState.state
  176. return nextStateAndOutput.output
  177. case var .draining(draining):
  178. let nextStateAndOutput = draining.cancel()
  179. self.state = nextStateAndOutput.nextState.state
  180. return nextStateAndOutput.output
  181. case var .finished(finished):
  182. let nextStateAndOutput = finished.cancel()
  183. self.state = nextStateAndOutput.nextState.state
  184. return nextStateAndOutput.output
  185. }
  186. }
  187. @inlinable
  188. mutating func handlerInvoked(requestHeaders: HPACKHeaders) {
  189. switch self.state {
  190. case var .idle(idle):
  191. let nextStateAndOutput = idle.handlerInvoked(requestHeaders: requestHeaders)
  192. self.state = nextStateAndOutput.nextState.state
  193. return nextStateAndOutput.output
  194. case .handling:
  195. preconditionFailure()
  196. case .draining:
  197. preconditionFailure()
  198. case .finished:
  199. preconditionFailure()
  200. }
  201. }
  202. }
  203. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  204. extension ServerHandlerStateMachine {
  205. /// The possible states the state machine may be in.
  206. @usableFromInline
  207. internal enum State {
  208. case idle(ServerHandlerStateMachine.Idle)
  209. case handling(ServerHandlerStateMachine.Handling)
  210. case draining(ServerHandlerStateMachine.Draining)
  211. case finished(ServerHandlerStateMachine.Finished)
  212. }
  213. }
  214. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  215. extension ServerHandlerStateMachine {
  216. /// The next state to transition to and any output which may be produced as a
  217. /// result of a substate handling an action.
  218. @usableFromInline
  219. internal struct NextStateAndOutput<NextState, Output> {
  220. @usableFromInline
  221. internal var nextState: NextState
  222. @usableFromInline
  223. internal var output: Output
  224. @inlinable
  225. internal init(nextState: NextState, output: Output) {
  226. self.nextState = nextState
  227. self.output = output
  228. }
  229. }
  230. }
  231. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  232. extension ServerHandlerStateMachine.NextStateAndOutput where Output == Void {
  233. @inlinable
  234. internal init(nextState: NextState) {
  235. self.nextState = nextState
  236. self.output = ()
  237. }
  238. }
  239. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  240. extension ServerHandlerStateMachine.Idle {
  241. /// States which can be reached directly from 'Idle'.
  242. @usableFromInline
  243. internal struct NextState {
  244. @usableFromInline
  245. let state: ServerHandlerStateMachine.State
  246. @inlinable
  247. internal init(_state: ServerHandlerStateMachine.State) {
  248. self.state = _state
  249. }
  250. @inlinable
  251. internal static func idle(_ state: ServerHandlerStateMachine.Idle) -> Self {
  252. return Self(_state: .idle(state))
  253. }
  254. @inlinable
  255. internal static func handling(
  256. from: ServerHandlerStateMachine.Idle,
  257. requestHeaders: HPACKHeaders
  258. ) -> Self {
  259. return Self(_state: .handling(.init(from: from, requestHeaders: requestHeaders)))
  260. }
  261. @inlinable
  262. internal static func finished(from: ServerHandlerStateMachine.Idle) -> Self {
  263. return Self(_state: .finished(.init(from: from)))
  264. }
  265. }
  266. }
  267. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  268. extension ServerHandlerStateMachine.Handling {
  269. /// States which can be reached directly from 'Handling'.
  270. @usableFromInline
  271. internal struct NextState {
  272. @usableFromInline
  273. let state: ServerHandlerStateMachine.State
  274. @inlinable
  275. internal init(_state: ServerHandlerStateMachine.State) {
  276. self.state = _state
  277. }
  278. @inlinable
  279. internal static func handling(_ state: ServerHandlerStateMachine.Handling) -> Self {
  280. return Self(_state: .handling(state))
  281. }
  282. @inlinable
  283. internal static func draining(from: ServerHandlerStateMachine.Handling) -> Self {
  284. return Self(_state: .draining(.init(from: from)))
  285. }
  286. @inlinable
  287. internal static func finished(from: ServerHandlerStateMachine.Handling) -> Self {
  288. return Self(_state: .finished(.init(from: from)))
  289. }
  290. }
  291. }
  292. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  293. extension ServerHandlerStateMachine.Draining {
  294. /// States which can be reached directly from 'Draining'.
  295. @usableFromInline
  296. internal struct NextState {
  297. @usableFromInline
  298. let state: ServerHandlerStateMachine.State
  299. @inlinable
  300. internal init(_state: ServerHandlerStateMachine.State) {
  301. self.state = _state
  302. }
  303. @inlinable
  304. internal static func draining(_ state: ServerHandlerStateMachine.Draining) -> Self {
  305. return Self(_state: .draining(state))
  306. }
  307. @inlinable
  308. internal static func finished(from: ServerHandlerStateMachine.Draining) -> Self {
  309. return Self(_state: .finished(.init(from: from)))
  310. }
  311. }
  312. }
  313. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  314. extension ServerHandlerStateMachine.Finished {
  315. /// States which can be reached directly from 'Finished'.
  316. @usableFromInline
  317. internal struct NextState {
  318. @usableFromInline
  319. let state: ServerHandlerStateMachine.State
  320. @inlinable
  321. init(_state: ServerHandlerStateMachine.State) {
  322. self.state = _state
  323. }
  324. @inlinable
  325. internal static func finished(_ state: ServerHandlerStateMachine.Finished) -> Self {
  326. return Self(_state: .finished(state))
  327. }
  328. }
  329. }
  330. #endif // compiler(>=5.6)