client-call-clientstreaming.swift 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /// {{ method|methodDescriptorName }} (Client Streaming)
  2. {{ access }} protocol {{ .|call:file,service,method }} {
  3. /// Call this to send each message in the request stream. Nonblocking.
  4. func send(_ message:{{ method|input }}, errorHandler:@escaping (Error)->()) throws
  5. /// Call this to close the connection and wait for a response. Blocking.
  6. func closeAndReceive() throws -> {{ method|output }}
  7. /// Call this to close the connection and wait for a response. Nonblocking.
  8. func closeAndReceive(completion:@escaping ({{ method|output }}?, {{ .|clienterror:file,service }}?)->()) throws
  9. /// Cancel the call.
  10. func cancel()
  11. }
  12. {{ access }} extension {{ .|call:file,service,method }} {
  13. func closeAndReceive() throws -> {{ method|output }} {
  14. var returnError : {{ .|clienterror:file,service }}?
  15. var returnResponse : {{ method|output }}!
  16. let sem = DispatchSemaphore(value: 0)
  17. do {
  18. try closeAndReceive() {response, error in
  19. returnResponse = response
  20. returnError = error
  21. sem.signal()
  22. }
  23. _ = sem.wait(timeout: DispatchTime.distantFuture)
  24. } catch (let error) {
  25. throw error
  26. }
  27. if let returnError = returnError {
  28. throw returnError
  29. }
  30. return returnResponse
  31. }
  32. }
  33. fileprivate final class {{ .|call:file,service,method }}Impl: {{ .|call:file,service,method }} {
  34. private var call : Call
  35. /// Create a call.
  36. init(_ channel: Channel) {
  37. self.call = channel.makeCall("{{ .|path:file,service,method }}")
  38. }
  39. /// Call this to start a call. Nonblocking.
  40. func start(metadata:Metadata, completion:@escaping (CallResult)->())
  41. throws -> {{ .|call:file,service,method }} {
  42. try self.call.start(.clientStreaming, metadata:metadata, completion:completion)
  43. return self
  44. }
  45. func send(_ message:{{ method|input }}, errorHandler:@escaping (Error)->()) throws {
  46. let messageData = try message.serializedData()
  47. try call.sendMessage(data:messageData, errorHandler:errorHandler)
  48. }
  49. func closeAndReceive(completion:@escaping ({{ method|output }}?, {{ .|clienterror:file,service }}?)->()) throws {
  50. do {
  51. try call.receiveMessage() {(responseData) in
  52. if let responseData = responseData,
  53. let response = try? {{ method|output }}(serializedData:responseData) {
  54. completion(response, nil)
  55. } else {
  56. completion(nil, {{ .|clienterror:file,service }}.invalidMessageReceived)
  57. }
  58. }
  59. try call.close(completion:{})
  60. } catch (let error) {
  61. throw error
  62. }
  63. }
  64. func cancel() {
  65. call.cancel()
  66. }
  67. }
  68. //-{% if generateTestStubs %}
  69. /// Simple fake implementation of {{ .|call:file,service,method }}
  70. /// stores sent values for later verification and finall returns a previously-defined result.
  71. class {{ .|call:file,service,method }}TestStub: {{ .|call:file,service,method }} {
  72. var inputs: [{{ method|input }}] = []
  73. var output: {{ method|output }}?
  74. func send(_ message:{{ method|input }}, errorHandler:@escaping (Error)->()) throws {
  75. inputs.append(message)
  76. }
  77. func closeAndReceive(completion:@escaping ({{ method|output }}?, {{ .|clienterror:file,service }}?)->()) throws {
  78. completion(output!, nil)
  79. }
  80. func cancel() { }
  81. }
  82. //-{% endif %}