@Override public void init() { super.init(); level = 0; }
/** * Create an renderer using the specified executor instead of the default one which should be used for production. * Using a custom executor is useful for tests to avoid creating new threads for each renderer registry. * * @param executor the executor to use or null to use the default executor suitable for production */ public AsynchronousSectionedRenderer(Executor executor) { isInitialized = false; if (executor == null) { renderingExecutor = createExecutor(); renderingExecutorIsOwned = true; } else { renderingExecutor = executor; renderingExecutorIsOwned = false; } }
/** * Initiate rendering before handover to rendering threads. * This is rendering which happens before the Response is returned from the main chain, * caused by freezing of DataLists. * At this point the worker thread still owns the Response, so all this rendering must happen * on the caller thread invoking freeze (that is, on the thread calling this). */ public final ListenableFuture<Boolean> renderBeforeHandover(OutputStream stream, RESPONSE response, Execution execution, Request request) { beforeHandoverMode = true; if ( ! isInitialized) throw new IllegalStateException("render() invoked before init()."); return startRender(stream, response, execution, request); }
/** * <p>Render this response using the renderer's own threads and return a future indicating whether the rendering * was successful. The data list tree will be traversed asynchronously, and * the pertinent methods will be called as data becomes available.</p> * * <p>If rendering fails, the exception causing this will be wrapped in an * ExecutionException and thrown from blocked calls to Future.get()</p> * * @return a future indicating whether rendering was successful */ @Override public final ListenableFuture<Boolean> render(OutputStream stream, RESPONSE response, Execution execution, Request request) { if (beforeHandoverMode) { // rendering has already started or is already complete beforeHandoverMode = false; if ( ! dataListListenerStack.isEmpty() && dataListListenerStack.getFirst().list.incoming().isComplete()) { // We're not waiting for async completion, so kick off more rendering due to the implicit complete // (return Response from chain) causing this method to be called getExecutor().execute(dataListListenerStack.getFirst()); } return success; } else { // This is the start of rendering return startRender(stream, response, execution, request); } }
@Override public void deconstruct() { super.deconstruct(); if (renderingExecutorIsOwned && renderingExecutor instanceof ThreadPoolExecutor) shutdown((ThreadPoolExecutor) renderingExecutor); }
@Override public void render(OutputStream output, ContentChannel networkChannel, CompletionHandler handler) throws IOException { if (rendererCopy instanceof AsynchronousSectionedRenderer) { AsynchronousSectionedRenderer<Result> renderer = (AsynchronousSectionedRenderer<Result>) rendererCopy; renderer.setNetworkWiring(networkChannel, handler); } try { try { waitableRender(output); } finally { if (!(rendererCopy instanceof AsynchronousSectionedRenderer)) { output.flush(); } } } finally { if (networkChannel != null && !(rendererCopy instanceof AsynchronousSectionedRenderer)) { networkChannel.close(handler); } } }
private ListenableFuture<Boolean> startRender(OutputStream stream, RESPONSE response, Execution execution, Request request) { this.response = response; this.stream = stream; this.execution = execution; DataListListener parentOfTopLevelListener = new DataListListener(new ParentOfTopLevel(request,response.data()), null); dataListListenerStack.addFirst(parentOfTopLevelListener); success = SettableFuture.create(); try { getExecutor().execute(parentOfTopLevelListener); } catch (RejectedExecutionException e) { parentOfTopLevelListener.closeIO(e); } return success; }
@Override public void run() { if (execution == null || response == null) throw new NullPointerException("Uninitialized freeze listener"); if (channel instanceof LazyContentChannel) ((LazyContentChannel)channel).setHttpResponse(getHttpResponse(response)); // Render if we have a renderer capable of it if (getRenderer() instanceof AsynchronousSectionedRenderer) { ((AsynchronousSectionedRenderer) getRenderer()).renderBeforeHandover(new ContentChannelOutputStream(channel), response, execution, request); } }
@Override public void init() { super.init(); writer = null; }
@Override public void init() { super.init(); writer = null; }
/** * Initialize mutable, per-result set state here. */ @Override public void init() { long time = System.currentTimeMillis(); super.init(); // Important! The base class needs to initialize itself. heading = "Renderer initialized: " + time; } }
@Override public void init() { super.init(); debugRendering = false; setGenerator(null, debugRendering); renderedChildren = null; timeSource = System::currentTimeMillis; stream = null; }