private void render(HttpRequest request, HttpResponse httpResponse, LazyContentChannel channel, long startTime) {
        LoggingCompletionHandler logOnCompletion = null;
        ContentChannelOutputStream output = null;
        try {
            output = httpResponse.maxPendingBytes() > 0 ? new MaxPendingContentChannelOutputStream(channel, httpResponse.maxPendingBytes())
                                                        : new ContentChannelOutputStream(channel);
            logOnCompletion = createLoggingCompletionHandler(startTime, System.currentTimeMillis(),
                                                             httpResponse, request, output);

            addResponseHeaders(httpResponse, startTime);

            if (httpResponse instanceof AsyncHttpResponse) {
                ((AsyncHttpResponse) httpResponse).render(output, channel, logOnCompletion);
            } else {
                httpResponse.render(output);
                if (logOnCompletion != null)
                    logOnCompletion.markCommitStart();
                output.flush();
            }
        }
        catch (IOException e) {
            metric.add(RENDERING_ERRORS, 1, null);
            long time = System.currentTimeMillis() - startTime;
            log.log(time < 900 ? Level.INFO : Level.WARNING,
                    "IO error while responding to  [" + request.getUri() + "] (total time " + time + " ms) ", e);
            try { output.flush(); } catch (Exception ignored) { }
        } finally {
            if (channel != null && ! (httpResponse instanceof AsyncHttpResponse)) {
                channel.close(logOnCompletion);
            }
        }
    }
Render and return whether the channel was closed
container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java