call.pyx.pxi 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # Copyright 2015 gRPC authors.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. cdef class Call:
  15. def __cinit__(self):
  16. # Create an *empty* call
  17. fork_handlers_and_grpc_init()
  18. self.c_call = NULL
  19. self.references = []
  20. def _start_batch(self, operations, tag, retain_self):
  21. if not self.is_valid:
  22. raise ValueError("invalid call object cannot be used from Python")
  23. cdef _BatchOperationTag batch_operation_tag = _BatchOperationTag(
  24. tag, operations, self if retain_self else None)
  25. batch_operation_tag.prepare()
  26. cpython.Py_INCREF(batch_operation_tag)
  27. cdef grpc_call_error error
  28. with nogil:
  29. error = grpc_call_start_batch(
  30. self.c_call, batch_operation_tag.c_ops, batch_operation_tag.c_nops,
  31. <cpython.PyObject *>batch_operation_tag, NULL)
  32. return error
  33. def start_client_batch(self, operations, tag):
  34. # We don't reference this call in the operations tag because
  35. # it should be cancelled when it goes out of scope
  36. return self._start_batch(operations, tag, False)
  37. def start_server_batch(self, operations, tag):
  38. return self._start_batch(operations, tag, True)
  39. def cancel(
  40. self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE,
  41. details=None):
  42. details = str_to_bytes(details)
  43. if not self.is_valid:
  44. raise ValueError("invalid call object cannot be used from Python")
  45. if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE):
  46. raise ValueError("if error_code is specified, so must details "
  47. "(and vice-versa)")
  48. cdef grpc_call_error result
  49. cdef char *c_details = NULL
  50. if error_code != GRPC_STATUS__DO_NOT_USE:
  51. self.references.append(details)
  52. c_details = details
  53. with nogil:
  54. result = grpc_call_cancel_with_status(
  55. self.c_call, error_code, c_details, NULL)
  56. return result
  57. else:
  58. with nogil:
  59. result = grpc_call_cancel(self.c_call, NULL)
  60. return result
  61. def set_credentials(self, CallCredentials call_credentials not None):
  62. cdef grpc_call_credentials *c_call_credentials = call_credentials.c()
  63. cdef grpc_call_error call_error = grpc_call_set_credentials(
  64. self.c_call, c_call_credentials)
  65. grpc_call_credentials_release(c_call_credentials)
  66. return call_error
  67. def peer(self):
  68. cdef char *peer = NULL
  69. with nogil:
  70. peer = grpc_call_get_peer(self.c_call)
  71. result = <bytes>peer
  72. with nogil:
  73. gpr_free(peer)
  74. return result
  75. def __dealloc__(self):
  76. with nogil:
  77. if self.c_call != NULL:
  78. grpc_call_unref(self.c_call)
  79. grpc_shutdown()
  80. # The object *should* always be valid from Python. Used for debugging.
  81. @property
  82. def is_valid(self):
  83. return self.c_call != NULL
  84. def _custom_op_on_c_call(self, int op):
  85. return _custom_op_on_c_call(op, self.c_call)