UnaryCallHandler.swift 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Copyright 2019, 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 Foundation
  17. import SwiftProtobuf
  18. import NIO
  19. import NIOHTTP1
  20. /// Handles unary calls. Calls the observer block with the request message.
  21. ///
  22. /// - The observer block is implemented by the framework user and returns a future containing the call result.
  23. /// - To return a response to the client, the framework user should complete that future
  24. /// (similar to e.g. serving regular HTTP requests in frameworks such as Vapor).
  25. public class UnaryCallHandler<RequestMessage: Message, ResponseMessage: Message>: BaseCallHandler<RequestMessage, ResponseMessage> {
  26. public typealias EventObserver = (RequestMessage) -> EventLoopFuture<ResponseMessage>
  27. private var eventObserver: EventObserver?
  28. private var callContext: UnaryResponseCallContext<ResponseMessage>?
  29. public init(channel: Channel, request: HTTPRequestHead, errorDelegate: ServerErrorDelegate?, eventObserverFactory: (UnaryResponseCallContext<ResponseMessage>) -> EventObserver) {
  30. super.init(errorDelegate: errorDelegate)
  31. let callContext = UnaryResponseCallContextImpl<ResponseMessage>(channel: channel, request: request, errorDelegate: errorDelegate)
  32. self.callContext = callContext
  33. self.eventObserver = eventObserverFactory(callContext)
  34. callContext.responsePromise.futureResult.whenComplete { _ in
  35. // When done, reset references to avoid retain cycles.
  36. self.eventObserver = nil
  37. self.callContext = nil
  38. }
  39. }
  40. public override func processMessage(_ message: RequestMessage) throws {
  41. guard let eventObserver = self.eventObserver,
  42. let context = self.callContext else {
  43. throw GRPCError.server(.tooManyRequests)
  44. }
  45. let resultFuture = eventObserver(message)
  46. resultFuture
  47. // Fulfill the response promise with whatever response (or error) the framework user has provided.
  48. .cascade(to: context.responsePromise)
  49. self.eventObserver = nil
  50. }
  51. public override func endOfStreamReceived() throws {
  52. if self.eventObserver != nil {
  53. throw GRPCError.server(.noRequestsButOneExpected)
  54. }
  55. }
  56. override func sendErrorStatus(_ status: GRPCStatus) {
  57. callContext?.responsePromise.fail(status)
  58. }
  59. }