Example #1
0
def _handle_event(event, state, response_deserializer):
    callbacks = []
    for batch_operation in event.batch_operations:
        operation_type = batch_operation.type()
        state.due.remove(operation_type)
        if operation_type == cygrpc.OperationType.receive_initial_metadata:
            state.initial_metadata = batch_operation.initial_metadata()
        elif operation_type == cygrpc.OperationType.receive_message:
            serialized_response = batch_operation.message()
            if serialized_response is not None:
                response = _common.deserialize(serialized_response,
                                               response_deserializer)
                if response is None:
                    details = 'Exception deserializing response!'
                    _abort(state, grpc.StatusCode.INTERNAL, details)
                else:
                    state.response = response
        elif operation_type == cygrpc.OperationType.receive_status_on_client:
            state.trailing_metadata = batch_operation.trailing_metadata()
            if state.code is None:
                code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
                    batch_operation.code())
                if code is None:
                    state.code = grpc.StatusCode.UNKNOWN
                    state.details = _unknown_code_details(
                        code, batch_operation.details())
                else:
                    state.code = code
                    state.details = batch_operation.details()
                    state.debug_error_string = batch_operation.error_string()
            callbacks.extend(state.callbacks)
            state.callbacks = None
    return callbacks
Example #2
0
def _handle_event(event, state, response_deserializer):
    callbacks = []
    for batch_operation in event.batch_operations:
        operation_type = batch_operation.type()
        state.due.remove(operation_type)
        if operation_type == cygrpc.OperationType.receive_initial_metadata:
            state.initial_metadata = batch_operation.initial_metadata()
        elif operation_type == cygrpc.OperationType.receive_message:
            serialized_response = batch_operation.message()
            if serialized_response is not None:
                response = _common.deserialize(serialized_response,
                                               response_deserializer)
                if response is None:
                    details = 'Exception deserializing response!'
                    _abort(state, grpc.StatusCode.INTERNAL, details)
                else:
                    state.response = response
        elif operation_type == cygrpc.OperationType.receive_status_on_client:
            state.trailing_metadata = batch_operation.trailing_metadata()
            if state.code is None:
                code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
                    batch_operation.code())
                if code is None:
                    state.code = grpc.StatusCode.UNKNOWN
                    state.details = _unknown_code_details(
                        code, batch_operation.details())
                else:
                    state.code = code
                    state.details = batch_operation.details()
                    state.debug_error_string = batch_operation.error_string()
            callbacks.extend(state.callbacks)
            state.callbacks = None
    return callbacks
Example #3
0
    async def __call__(self,
                       request,
                       timeout=None,
                       metadata=None,
                       credentials=None,
                       wait_for_ready=None,
                       compression=None):

        if timeout:
            raise NotImplementedError("TODO: timeout not implemented yet")

        if metadata:
            raise NotImplementedError("TODO: metadata not implemented yet")

        if credentials:
            raise NotImplementedError("TODO: credentials not implemented yet")

        if wait_for_ready:
            raise NotImplementedError(
                "TODO: wait_for_ready not implemented yet")

        if compression:
            raise NotImplementedError("TODO: compression not implemented yet")

        response = await self._channel.unary_unary(
            self._method, _common.serialize(request, self._request_serializer))

        return _common.deserialize(response, self._response_deserializer)
Example #4
0
    async def _conduct_rpc(self) -> ResponseType:
        try:
            serialized_response = await self._cython_call.stream_unary(
                self._metadata, self._metadata_sent_observer)
        except asyncio.CancelledError:
            if not self.cancelled():
                self.cancel()

        if self._cython_call.is_ok():
            return _common.deserialize(serialized_response,
                                       self._response_deserializer)
        else:
            return cygrpc.EOF
Example #5
0
    async def _conduct_rpc(self) -> ResponseType:
        try:
            serialized_response = await self._cython_call.stream_unary(
                self._metadata, self._metadata_sent_observer)
        except asyncio.CancelledError:
            if not self.cancelled():
                self.cancel()

        # Raises RpcError if the RPC failed or cancelled
        await self._raise_for_status()

        return _common.deserialize(serialized_response,
                                   self._response_deserializer)
Example #6
0
    async def _process(self) -> ResponseType:
        await self._call
        async for serialized_response in self._bytes_aiter:
            if self._cancellation.done():
                await self._status
            if self._status.done():
                # Raises pre-maturely if final status received here. Generates
                # more helpful stack trace for end users.
                await self._raise_rpc_error_if_not_ok()
            yield _common.deserialize(serialized_response,
                                      self._response_deserializer)

        await self._raise_rpc_error_if_not_ok()
Example #7
0
    async def __call__(self,
                       request,
                       timeout=None,
                       metadata=None,
                       credentials=None,
                       wait_for_ready=None,
                       compression=None):
        """Asynchronously invokes the underlying RPC.

        Args:
          request: The request value for the RPC.
          timeout: An optional duration of time in seconds to allow
            for the RPC.
          metadata: Optional :term:`metadata` to be transmitted to the
            service-side of the RPC.
          credentials: An optional CallCredentials for the RPC. Only valid for
            secure Channel.
          wait_for_ready: This is an EXPERIMENTAL argument. An optional
            flag to enable wait for ready mechanism
          compression: An element of grpc.compression, e.g.
            grpc.compression.Gzip. This is an EXPERIMENTAL option.

        Returns:
          The response value for the RPC.

        Raises:
          RpcError: Indicating that the RPC terminated with non-OK status. The
            raised RpcError will also be a Call for the RPC affording the RPC's
            metadata, status code, and details.
        """

        if timeout:
            raise NotImplementedError("TODO: timeout not implemented yet")

        if metadata:
            raise NotImplementedError("TODO: metadata not implemented yet")

        if credentials:
            raise NotImplementedError("TODO: credentials not implemented yet")

        if wait_for_ready:
            raise NotImplementedError(
                "TODO: wait_for_ready not implemented yet")

        if compression:
            raise NotImplementedError("TODO: compression not implemented yet")

        response = await self._channel.unary_unary(
            self._method, _common.serialize(request, self._request_serializer))

        return _common.deserialize(response, self._response_deserializer)
Example #8
0
    async def _read(self) -> ResponseType:
        # Wait for the request being sent
        await self._preparation

        # Reads response message from Core
        try:
            raw_response = await self._cython_call.receive_serialized_message()
        except asyncio.CancelledError:
            if not self.cancelled():
                self.cancel()
            await self._raise_for_status()

        if raw_response is cygrpc.EOF:
            return cygrpc.EOF
        else:
            return _common.deserialize(raw_response,
                                       self._response_deserializer)
Example #9
0
    async def _read(self) -> ResponseType:
        # Wait for the request being sent
        await self._send_unary_request_task

        # Reads response message from Core
        try:
            raw_response = await self._cython_call.receive_serialized_message()
        except asyncio.CancelledError:
            if self._code != grpc.StatusCode.CANCELLED:
                self.cancel()
            raise

        if raw_response is None:
            return None
        else:
            return _common.deserialize(raw_response,
                                       self._response_deserializer)
Example #10
0
 def receive_message(receive_message_event):
   serialized_request = _serialized_request(receive_message_event)
   if serialized_request is None:
     with state.condition:
       if state.client is _OPEN:
         state.client = _CLOSED
       state.condition.notify_all()
       return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
   else:
     request = _common.deserialize(serialized_request, request_deserializer)
     with state.condition:
       if request is None:
         _abort(
             state, call, cygrpc.StatusCode.internal,
             b'Exception deserializing request!')
       else:
         state.request = request
       state.condition.notify_all()
       return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
Example #11
0
 def receive_message(receive_message_event):
     serialized_request = _serialized_request(receive_message_event)
     if serialized_request is None:
         with state.condition:
             if state.client is _OPEN:
                 state.client = _CLOSED
             state.condition.notify_all()
             return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
     else:
         request = _common.deserialize(serialized_request,
                                       request_deserializer)
         with state.condition:
             if request is None:
                 _abort(state, call, cygrpc.StatusCode.internal,
                        b'Exception deserializing request!')
             else:
                 state.request = request
             state.condition.notify_all()
             return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
Example #12
0
    async def _invoke(self) -> ResponseType:
        serialized_request = _common.serialize(self._request,
                                               self._request_serializer)

        # NOTE(lidiz) asyncio.CancelledError is not a good transport for status,
        # because the asyncio.Task class do not cache the exception object.
        # https://github.com/python/cpython/blob/edad4d89e357c92f70c0324b937845d652b20afd/Lib/asyncio/tasks.py#L785
        try:
            serialized_response = await self._cython_call.unary_unary(
                serialized_request, self._metadata)
        except asyncio.CancelledError:
            if not self.cancelled():
                self.cancel()

        if self._cython_call.is_ok():
            return _common.deserialize(serialized_response,
                                       self._response_deserializer)
        else:
            return cygrpc.EOF
Example #13
0
    def __await__(self):
        """Wait till the ongoing RPC request finishes.

        Returns:
          Response of the RPC call.

        Raises:
          AioRpcError: Indicating that the RPC terminated with non-OK status.
          asyncio.CancelledError: Indicating that the RPC was canceled.
        """
        # We can not relay on the `done()` method since some exceptions
        # might be pending to be catched, like `asyncio.CancelledError`.
        if self._response:
            return self._response
        elif self._exception:
            raise self._exception

        try:
            buffer_ = yield from self._call.__await__()
        except cygrpc.AioRpcError as aio_rpc_error:
            self._state = _RpcState.ABORT
            self._code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE[
                aio_rpc_error.code()]
            self._details = aio_rpc_error.details()
            self._initial_metadata = aio_rpc_error.initial_metadata()
            self._trailing_metadata = aio_rpc_error.trailing_metadata()

            # Propagates the pure Python class
            self._exception = AioRpcError(self._code, self._details,
                                          self._initial_metadata,
                                          self._trailing_metadata)
            raise self._exception from aio_rpc_error
        except asyncio.CancelledError as cancel_error:
            # _state, _code, _details are managed in the `cancel` method
            self._exception = cancel_error
            raise

        self._response = _common.deserialize(buffer_,
                                             self._response_deserializer)
        self._code = grpc.StatusCode.OK
        self._state = _RpcState.FINISHED
        return self._response
Example #14
0
    async def _invoke(self) -> ResponseType:
        serialized_request = _common.serialize(self._request,
                                               self._request_serializer)

        # NOTE(lidiz) asyncio.CancelledError is not a good transport for
        # status, since the Task class do not cache the exact
        # asyncio.CancelledError object. So, the solution is catching the error
        # in Cython layer, then cancel the RPC and update the status, finally
        # re-raise the CancelledError.
        serialized_response = await self._channel.unary_unary(
            self._method,
            serialized_request,
            self._deadline,
            self._cancellation,
            self._set_initial_metadata,
            self._set_status,
        )
        await self._raise_rpc_error_if_not_ok()

        return _common.deserialize(serialized_response,
                                   self._response_deserializer)
Example #15
0
    async def _invoke(self) -> ResponseType:
        serialized_request = _common.serialize(self._request,
                                               self._request_serializer)

        # NOTE(lidiz) asyncio.CancelledError is not a good transport for status,
        # because the asyncio.Task class do not cache the exception object.
        # https://github.com/python/cpython/blob/edad4d89e357c92f70c0324b937845d652b20afd/Lib/asyncio/tasks.py#L785
        try:
            serialized_response = await self._cython_call.unary_unary(
                serialized_request,
                self._set_initial_metadata,
                self._set_status,
            )
        except asyncio.CancelledError:
            if self._code != grpc.StatusCode.CANCELLED:
                self.cancel()

        # Raises here if RPC failed or cancelled
        await self._raise_for_status()

        return _common.deserialize(serialized_response,
                                   self._response_deserializer)