Search in sources :

Example 1 with RPCTInfo

use of org.apache.hadoop.hbase.shaded.protobuf.generated.TracingProtos.RPCTInfo in project hbase by apache.

the class ServerRpcConnection method processRequest.

/**
 * @param buf
 *          Has the request header and the request param and optionally
 *          encoded data buffer all in this one array.
 * @throws IOException
 * @throws InterruptedException
 */
protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {
    long totalRequestSize = buf.limit();
    int offset = 0;
    // Here we read in the header. We avoid having pb
    // do its default 4k allocation for CodedInputStream. We force it to use
    // backing array.
    CodedInputStream cis;
    if (buf.hasArray()) {
        cis = UnsafeByteOperations.unsafeWrap(buf.array(), 0, buf.limit()).newCodedInput();
    } else {
        cis = UnsafeByteOperations.unsafeWrap(new ByteBuffByteInput(buf, 0, buf.limit()), 0, buf.limit()).newCodedInput();
    }
    cis.enableAliasing(true);
    int headerSize = cis.readRawVarint32();
    offset = cis.getTotalBytesRead();
    Message.Builder builder = RequestHeader.newBuilder();
    ProtobufUtil.mergeFrom(builder, cis, headerSize);
    RequestHeader header = (RequestHeader) builder.build();
    offset += headerSize;
    TextMapGetter<RPCTInfo> getter = new TextMapGetter<RPCTInfo>() {

        @Override
        public Iterable<String> keys(RPCTInfo carrier) {
            return carrier.getHeadersMap().keySet();
        }

        @Override
        public String get(RPCTInfo carrier, String key) {
            return carrier.getHeadersMap().get(key);
        }
    };
    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator().extract(Context.current(), header.getTraceInfo(), getter);
    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);
    try (Scope scope = span.makeCurrent()) {
        int id = header.getCallId();
        if (RpcServer.LOG.isTraceEnabled()) {
            RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header) + " totalRequestSize: " + totalRequestSize + " bytes");
        }
        // total request.
        if ((totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum()) > this.rpcServer.maxQueueSizeInBytes) {
            final ServerCall<?> callTooBig = createCall(id, this.service, null, null, null, null, totalRequestSize, null, 0, this.callCleanup);
            this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);
            callTooBig.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION, "Call queue is full on " + this.rpcServer.server.getServerName() + ", is hbase.ipc.server.max.callqueue.size too small?");
            callTooBig.sendResponseIfReady();
            return;
        }
        MethodDescriptor md = null;
        Message param = null;
        CellScanner cellScanner = null;
        try {
            if (header.hasRequestParam() && header.getRequestParam()) {
                md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());
                if (md == null) {
                    throw new UnsupportedOperationException(header.getMethodName());
                }
                builder = this.service.getRequestPrototype(md).newBuilderForType();
                cis.resetSizeCounter();
                int paramSize = cis.readRawVarint32();
                offset += cis.getTotalBytesRead();
                if (builder != null) {
                    ProtobufUtil.mergeFrom(builder, cis, paramSize);
                    param = builder.build();
                }
                offset += paramSize;
            } else {
                // currently header must have request param, so we directly throw
                // exception here
                String msg = "Invalid request header: " + TextFormat.shortDebugString(header) + ", should have param set in it";
                RpcServer.LOG.warn(msg);
                throw new DoNotRetryIOException(msg);
            }
            if (header.hasCellBlockMeta()) {
                buf.position(offset);
                ByteBuff dup = buf.duplicate();
                dup.limit(offset + header.getCellBlockMeta().getLength());
                cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec, this.compressionCodec, dup);
            }
        } catch (Throwable t) {
            InetSocketAddress address = this.rpcServer.getListenerAddress();
            String msg = (address != null ? address : "(channel closed)") + " is unable to read call parameter from client " + getHostAddress();
            RpcServer.LOG.warn(msg, t);
            this.rpcServer.metrics.exception(t);
            // version
            if (t instanceof LinkageError) {
                t = new DoNotRetryIOException(t);
            }
            // If the method is not present on the server, do not retry.
            if (t instanceof UnsupportedOperationException) {
                t = new DoNotRetryIOException(t);
            }
            ServerCall<?> readParamsFailedCall = createCall(id, this.service, null, null, null, null, totalRequestSize, null, 0, this.callCleanup);
            readParamsFailedCall.setResponse(null, null, t, msg + "; " + t.getMessage());
            readParamsFailedCall.sendResponseIfReady();
            return;
        }
        int timeout = 0;
        if (header.hasTimeout() && header.getTimeout() > 0) {
            timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());
        }
        ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner, totalRequestSize, this.addr, timeout, this.callCleanup);
        if (!this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {
            this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());
            this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);
            call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION, "Call queue is full on " + this.rpcServer.server.getServerName() + ", too many items queued ?");
            call.sendResponseIfReady();
        }
    }
}
Also used : Message(org.apache.hbase.thirdparty.com.google.protobuf.Message) DoNotRetryIOException(org.apache.hadoop.hbase.DoNotRetryIOException) CodedInputStream(org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream) InetSocketAddress(java.net.InetSocketAddress) ByteString(org.apache.hbase.thirdparty.com.google.protobuf.ByteString) Span(io.opentelemetry.api.trace.Span) CellScanner(org.apache.hadoop.hbase.CellScanner) RPCTInfo(org.apache.hadoop.hbase.shaded.protobuf.generated.TracingProtos.RPCTInfo) SingleByteBuff(org.apache.hadoop.hbase.nio.SingleByteBuff) ByteBuff(org.apache.hadoop.hbase.nio.ByteBuff) Context(io.opentelemetry.context.Context) TextMapGetter(io.opentelemetry.context.propagation.TextMapGetter) MethodDescriptor(org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor) Scope(io.opentelemetry.context.Scope) RequestHeader(org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader)

Aggregations

Span (io.opentelemetry.api.trace.Span)1 Context (io.opentelemetry.context.Context)1 Scope (io.opentelemetry.context.Scope)1 TextMapGetter (io.opentelemetry.context.propagation.TextMapGetter)1 InetSocketAddress (java.net.InetSocketAddress)1 CellScanner (org.apache.hadoop.hbase.CellScanner)1 DoNotRetryIOException (org.apache.hadoop.hbase.DoNotRetryIOException)1 ByteBuff (org.apache.hadoop.hbase.nio.ByteBuff)1 SingleByteBuff (org.apache.hadoop.hbase.nio.SingleByteBuff)1 RequestHeader (org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader)1 RPCTInfo (org.apache.hadoop.hbase.shaded.protobuf.generated.TracingProtos.RPCTInfo)1 ByteString (org.apache.hbase.thirdparty.com.google.protobuf.ByteString)1 CodedInputStream (org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream)1 MethodDescriptor (org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor)1 Message (org.apache.hbase.thirdparty.com.google.protobuf.Message)1