UnaryCallHandler.swift 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import Foundation
  2. import SwiftProtobuf
  3. import NIO
  4. import NIOHTTP1
  5. /// Handles unary calls. Calls the observer block with the request message.
  6. ///
  7. /// - The observer block is implemented by the framework user and returns a future containing the call result.
  8. /// - To return a response to the client, the framework user should complete that future
  9. /// (similar to e.g. serving regular HTTP requests in frameworks such as Vapor).
  10. public class UnaryCallHandler<RequestMessage: Message, ResponseMessage: Message>: BaseCallHandler<RequestMessage, ResponseMessage> {
  11. public typealias EventObserver = (RequestMessage) -> EventLoopFuture<ResponseMessage>
  12. private var eventObserver: EventObserver?
  13. private var context: UnaryResponseCallContext<ResponseMessage>?
  14. public init(channel: Channel, request: HTTPRequestHead, eventObserverFactory: (UnaryResponseCallContext<ResponseMessage>) -> EventObserver) {
  15. super.init()
  16. let context = UnaryResponseCallContextImpl<ResponseMessage>(channel: channel, request: request)
  17. self.context = context
  18. self.eventObserver = eventObserverFactory(context)
  19. context.responsePromise.futureResult.whenComplete {
  20. // When done, reset references to avoid retain cycles.
  21. self.eventObserver = nil
  22. self.context = nil
  23. }
  24. }
  25. public override func processMessage(_ message: RequestMessage) {
  26. guard let eventObserver = self.eventObserver,
  27. let context = self.context else {
  28. //! FIXME: Better handle this error?
  29. print("multiple messages received on unary call")
  30. return
  31. }
  32. let resultFuture = eventObserver(message)
  33. resultFuture
  34. // Fulfill the response promise with whatever response (or error) the framework user has provided.
  35. .cascade(promise: context.responsePromise)
  36. self.eventObserver = nil
  37. }
  38. }