private ListenableFuture sendRequestToAsyncHandler()

in tchannel-core/src/main/java/com/uber/tchannel/handlers/RequestRouter.java [241:288]


    private ListenableFuture<? extends Response> sendRequestToAsyncHandler(
        final AsyncRequestHandler asyncHandler, final Request request
    ) {
        // span used to trace this request
        // Tracer and TracingContext are only present when the channel is created with them
        // therefore can be null.
        final Span span = topChannel.getTracer() == null
            ? null
            : Tracing.startInboundSpan(request, topChannel.getTracer(), topChannel.getTracingContext());

        ListenableFuture<? extends Response> responseFuture = asyncHandler.handleAsync(request);

        // Add callback handlers that close out the tracing span and then proxy the response.
        Futures.addCallback(responseFuture, new FutureCallback<Response>() {
            @Override
            public void onSuccess(Response response) {
                if (response != null
                    && response.getResponseCode() == ResponseCode.Error
                    && span != null) {
                    span.setTag(Tags.ERROR, true);
                }

                closeRequestAndSpan();
            }

            @Override
            public void onFailure(@NotNull Throwable e) {
                if (span != null) {
                    span.setTag(Tags.ERROR, true);
                    span.log(ImmutableMap.of(Fields.ERROR_OBJECT, e));
                }
                closeRequestAndSpan();
            }

            private void closeRequestAndSpan() {
                request.releaseQuietly();
                if (span != null) {
                    span.finish();
                }
            }
        }, listeningExecutorService); // execute the callback asynchronously, not on the thread that resolves the future

        if (span != null) { // if we pushed something on tracing context stack in Tracing.startInboundSpan(...)
            topChannel.getTracingContext().popSpan(); // then pop it
        }

        return responseFuture;
    }