ServerHandlerStateMachine+Idle.swift 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  18. extension ServerHandlerStateMachine {
  19. /// In the 'Idle' state nothing has happened. To advance we must either receive metadata (i.e.
  20. /// the request headers) and invoke the handler, or we are cancelled.
  21. @usableFromInline
  22. internal struct Idle {
  23. typealias NextStateAndOutput<Output> = ServerHandlerStateMachine.NextStateAndOutput<
  24. ServerHandlerStateMachine.Idle.NextState,
  25. Output
  26. >
  27. /// A ref to the `UserInfo`. We hold on to this until we're ready to invoke the handler.
  28. let userInfoRef: Ref<UserInfo>
  29. /// A bag of bits required to construct a context passed to the user handler when it is invoked.
  30. let callHandlerContext: CallHandlerContext
  31. /// The state of the inbound stream, i.e. the request stream.
  32. internal private(set) var inboundState: ServerInterceptorStateMachine.InboundStreamState
  33. init(userInfoRef: Ref<UserInfo>, context: CallHandlerContext) {
  34. self.userInfoRef = userInfoRef
  35. self.callHandlerContext = context
  36. self.inboundState = .idle
  37. }
  38. mutating func handleMetadata() -> Self.NextStateAndOutput<HandleMetadataAction> {
  39. let action: HandleMetadataAction
  40. switch self.inboundState.receiveMetadata() {
  41. case .accept:
  42. // We tell the caller to invoke the handler immediately: they should then call
  43. // 'handlerInvoked' on the state machine which will cause a transition to the next state.
  44. action = .invokeHandler(self.userInfoRef, self.callHandlerContext)
  45. case .reject:
  46. action = .cancel
  47. }
  48. return .init(nextState: .idle(self), output: action)
  49. }
  50. mutating func handleMessage() -> Self.NextStateAndOutput<HandleMessageAction> {
  51. // We can't receive a message before the metadata, doing so is a protocol violation.
  52. return .init(nextState: .idle(self), output: .cancel)
  53. }
  54. mutating func handleEnd() -> Self.NextStateAndOutput<HandleEndAction> {
  55. // Receiving 'end' before we start is odd but okay, just cancel.
  56. return .init(nextState: .idle(self), output: .cancel)
  57. }
  58. mutating func handlerInvoked(
  59. context: GRPCAsyncServerCallContext
  60. ) -> Self.NextStateAndOutput<Void> {
  61. // The handler was invoked as a result of receiving metadata. Move to the next state.
  62. return .init(nextState: .handling(from: self, context: context))
  63. }
  64. mutating func cancel() -> Self.NextStateAndOutput<CancelAction> {
  65. // There's no handler to cancel. Move straight to finished.
  66. return .init(nextState: .finished(from: self), output: .none)
  67. }
  68. }
  69. }
  70. #endif // compiler(>=5.6)