Exemplo n.º 1
0
    def handle_request(self, request_stream, response_stream):
        try:
            method_path = request_stream.headers.get(":path")
            entrypoint = self.entrypoints[method_path]
        except KeyError:
            raise GrpcError(
                status=StatusCode.UNIMPLEMENTED, details="Method not found!"
            )

        encoding = request_stream.headers.get("grpc-encoding", "identity")
        if encoding not in SUPPORTED_ENCODINGS:
            raise GrpcError(
                status=StatusCode.UNIMPLEMENTED,
                details="Algorithm not supported: {}".format(encoding),
            )

        timeout = request_stream.headers.get("grpc-timeout")
        if timeout:
            timeout = unbucket_timeout(timeout)
            self.container.spawn_managed_thread(
                partial(self.timeout, request_stream, response_stream, timeout)
            )

        self.container.spawn_managed_thread(
            partial(entrypoint.handle_request, request_stream, response_stream)
        )
Exemplo n.º 2
0
    def handle_request(self, request_stream, response_stream):

        request = request_stream.consume(self.input_type)

        if self.cardinality in (Cardinality.UNARY_STREAM, Cardinality.UNARY_UNARY):
            request = next(request)

        context = GrpcContext(request_stream, response_stream)

        args = (request, context)
        kwargs = {}

        context_data = context_data_from_metadata(context.invocation_metadata())

        handle_result = partial(self.handle_result, response_stream)
        try:
            self.container.spawn_worker(
                self,
                args,
                kwargs,
                context_data=context_data,
                handle_result=handle_result,
            )
        except ContainerBeingKilled:
            raise GrpcError(
                status=StatusCode.UNAVAILABLE, details="Server shutting down"
            )
Exemplo n.º 3
0
    def test_close_with_error(self):
        stream = StreamBase(1)
        error = GrpcError("boom", "details", "error string")
        stream.close(error)

        assert stream.closed
        assert stream.queue.get() == error
Exemplo n.º 4
0
 def cleanup_on_exit(self):
     error = None
     try:
         yield
     except Exception:
         log.info(
             "ConnectionManager shutting down with error. Traceback:",
             exc_info=True,
         )
         error = GrpcError.from_exception(sys.exc_info(),
                                          code=StatusCode.UNAVAILABLE)
     finally:
         for send_stream in self.send_streams.values():
             if send_stream.closed:
                 continue  # stream.close() is idemponent but this prevents the log
             log.info(f"Terminating send stream {send_stream}"
                      f"{f' with error {error}' if error else ''}.")
             send_stream.close(error)
         for receive_stream in self.receive_streams.values():
             if receive_stream.closed:
                 continue  # stream.close() is idemponent but this prevents the log
             log.info(f"Terminating receive stream {receive_stream}"
                      f"{f' with error {error}' if error else ''}.")
             receive_stream.close(error)
         self.sock.close()
         self.stopped.set()
Exemplo n.º 5
0
    def test_consume_grpc_error(self):
        stream = ReceiveStream(1)
        error = GrpcError("boom", "details", "message")
        stream.queue.put(error)

        message_type = Mock()

        with pytest.raises(GrpcError):
            next(stream.consume(message_type))
Exemplo n.º 6
0
    def test_error_on_queue(self, generate_messages):
        stream = SendStream(1)
        stream.populate(generate_messages(count=2, length=20))

        error = GrpcError("boom", "details", "error string")
        stream.close(error)

        with pytest.raises(GrpcError):
            stream.flush_queue_to_buffer()
Exemplo n.º 7
0
 def timeout(self, send_stream, response_stream, deadline):
     start = time.time()
     while True:
         elapsed = time.time() - start
         if elapsed > deadline:
             error = GrpcError(status=StatusCode.DEADLINE_EXCEEDED,
                               details="Deadline Exceeded")
             response_stream.close(error)
             send_stream.close()
         time.sleep(0.001)
Exemplo n.º 8
0
 def send_stream(self, result):
     try:
         for item in result:
             self.send(item)
     except grpc.RpcError as exc:
         state = exc._state
         error = GrpcError(state.code, state.details,
                           status_from_metadata(state.trailing_metadata))
         self.send(error)
     self.send(self.ENDSTREAM, close=True)
Exemplo n.º 9
0
    def unary_grpc_error(self, request, context):
        maybe_echo_metadata(context)
        maybe_sleep(request)

        code = StatusCode.UNAUTHENTICATED
        message = "Not allowed!"

        raise GrpcError(code=code,
                        message=message,
                        status=make_status(code, message))
Exemplo n.º 10
0
 def send_stream(self, result):
     try:
         for item in result:
             self.send(item)
     except grpc.RpcError as exc:
         state = exc._state
         error = GrpcError(state.code, state.details,
                           state.debug_error_string)
         self.send(error)
     self.send(self.ENDSTREAM, close=True)
Exemplo n.º 11
0
    def test_error_on_queue(self, generate_messages):
        stream = SendStream(1)

        error = GrpcError("boom", "details")
        messages = itertools.chain(generate_messages(count=2, length=20),
                                   [error])

        stream.populate(messages)

        with pytest.raises(GrpcError):
            stream.flush_queue_to_buffer()
Exemplo n.º 12
0
    def test_stream_closed_with_error(self):
        stream = SendStream(1)

        error = GrpcError("boom", "details", "error string")
        stream.close(error)

        max_bytes = 10
        chunk_size = 5

        with pytest.raises(GrpcError):
            next(stream.read(max_bytes, chunk_size))
Exemplo n.º 13
0
    def handle_result(self, response_stream, worker_ctx, result, exc_info):

        if self.cardinality in (Cardinality.STREAM_UNARY, Cardinality.UNARY_UNARY):
            result = (result,)

        if exc_info is None:
            try:
                response_stream.populate(result)
            except Exception as exception:
                message = "Exception iterating responses: {}".format(exception)

                error = GrpcError(status=StatusCode.UNKNOWN, details=message)
                response_stream.close(error)
        else:
            error = GrpcError(
                status=StatusCode.UNKNOWN,
                details="Exception calling application: {}".format(exc_info[1]),
            )
            response_stream.close(error)

        return result, exc_info
Exemplo n.º 14
0
        def handler(exc_info, code=None, message=None):
            exc_type, exc, tb = exc_info

            code = code or StatusCode.PERMISSION_DENIED
            message = "Not allowed!"

            status = Status(
                code=STATUS_CODE_ENUM_TO_INT_MAP[code],
                message=message,
                details=[],  # don't include traceback
            )

            return GrpcError(code=code, message=message, status=status)
Exemplo n.º 15
0
 def timeout(self, request_stream, response_stream, deadline):
     start = time.time()
     while True:
         if request_stream.closed and response_stream.closed:
             break
         elapsed = time.time() - start
         if elapsed > deadline:
             request_stream.close()
             error = GrpcError(code=StatusCode.DEADLINE_EXCEEDED,
                               message="Deadline Exceeded")
             response_stream.close(error)
             break
         time.sleep(0.001)
Exemplo n.º 16
0
    def handle_result(self, response_stream, worker_ctx, result, exc_info):

        if self.cardinality in (Cardinality.STREAM_UNARY,
                                Cardinality.UNARY_UNARY):
            result = (result, )

        if exc_info is None:
            try:
                response_stream.populate(result)
            except Exception as exception:
                message = "Exception iterating responses: {}".format(exception)
                error = GrpcError.from_exception(sys.exc_info(),
                                                 message=message)

                response_stream.close(error)
        else:
            message = "Exception calling application: {}".format(exc_info[1])
            error = GrpcError.from_exception(exc_info, message=message)

            response_stream.close(error)

        return result, exc_info
Exemplo n.º 17
0
 def timeout(self, request_stream, response_stream, deadline):
     start = time.time()
     while True:
         elapsed = time.time() - start
         if elapsed > deadline:
             request_stream.close()
             # XXX does server actually need to do this according to the spec?
             # perhaps we could just close the stream.
             error = GrpcError(
                 status=StatusCode.DEADLINE_EXCEEDED, details="Deadline Exceeded"
             )
             response_stream.close(error)
             break
         time.sleep(0.001)
Exemplo n.º 18
0
    def send_data(self, stream_id):
        try:
            super().send_data(stream_id)
        except UnsupportedEncoding:

            response_stream = self.receive_streams[stream_id]
            request_stream = self.send_streams[stream_id]

            error = GrpcError(
                status=StatusCode.UNIMPLEMENTED,
                details="Algorithm not supported: {}".format(
                    request_stream.encoding),
            )
            response_stream.close(error)
            request_stream.close()
Exemplo n.º 19
0
    def stream_grpc_error(self, request, context):
        metadata = extract_metadata(context)
        maybe_echo_metadata(context)
        message = request.value * (request.multiplier or 1)
        for i in range(request.response_count):
            maybe_sleep(request)
            # raise on the last message
            if i == request.response_count - 1:

                code = StatusCode.RESOURCE_EXHAUSTED
                message = "Out of tokens!"

                raise GrpcError(
                    code=code,
                    message=message,
                    status=make_status(code, message),
                )
            yield ExampleReply(message=message, seqno=i + 1, metadata=metadata)
Exemplo n.º 20
0
    def trailers_received(self, event):
        """ Called when trailers are received on a stream.

        If the trailers contain an error, we should raise it here.
        """
        super().trailers_received(event)

        stream_id = event.stream_id
        response_stream = self.receive_streams.get(stream_id)
        if response_stream is None:
            self.conn.reset_stream(stream_id,
                                   error_code=ErrorCodes.PROTOCOL_ERROR)
            return

        trailers = response_stream.trailers

        if int(trailers.get("grpc-status", 0)) > 0:
            error = GrpcError.from_headers(trailers)
            response_stream.close(error)
Exemplo n.º 21
0
def execute(command, stub):
    method = getattr(stub, command.method_name)

    request = command.get_request()

    compression = command.kwargs.pop("compression", None)
    if compression:
        command.kwargs["metadata"] = list(command.kwargs.get(
            "metadata", [])) + [("grpc-internal-encoding-request", compression)
                                ]

    response_metadata = {}

    try:
        if command.cardinality in (Cardinality.STREAM_UNARY,
                                   Cardinality.UNARY_UNARY):
            response_future = method.future(request, **command.kwargs)
            response_metadata["code"] = response_future.code()
            response_metadata["details"] = response_future.details()
            response_metadata["initial_metadata"] = list(
                map(tuple, response_future.initial_metadata()))
            response_metadata["trailing_metadata"] = list(
                map(tuple, response_future.trailing_metadata()))
            response = response_future.result()
        else:
            # .future() interface for RPCs with STREAM responses not supported
            response = method(request, **command.kwargs)
    except grpc.RpcError as exc:
        state = exc._state
        response_metadata["code"] = state.code
        response_metadata["details"] = state.details

        response = GrpcError(state.code, state.details,
                             status_from_metadata(state.trailing_metadata))

    command.send_response(response)
    command.send_metadata(response_metadata)