client-call-serverstreaming.swift 2.9 KB

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