Source:
<code>@POST @Path( "{job_id}/content" ) public Response getContent( @PathParam( "job_id" ) String job_id ) throws IOException { UUID uuid = null; try { uuid = UUID.fromString( job_id ); } catch ( Exception e ) { logger.error( "Content: invalid UUID: " + job_id ); return get404(); } IPentahoAsyncExecutor executor = getExecutor(); if ( executor == null ) { return Response.serverError().build(); } final IPentahoSession session = PentahoSessionHolder.getSession(); Future<InputStream> future = executor.getFuture( uuid, session ); <START> <END> IAsyncReportState state = executor.getReportState( uuid, session ); if ( state == null ) { return get404(); } InputStream input = null; try { input = future.get(); } catch ( Exception e ) { logger.error( "Error generating report", e ); return Response.serverError().build(); } executor.cleanFuture( uuid, session ); StreamingOutput stream = new StreamingOutputWrapper( input ); MediaType mediaType = null; Response.ResponseBuilder response = null; try { mediaType = MediaType.valueOf( state.getMimeType() ); response = Response.ok( stream, mediaType ); } catch ( Exception e ) { logger.error( "can't determine JAX-RS media type for: " + state.getMimeType() ); response = Response.ok( stream, state.getMimeType() ); } CacheControl cacheControl = new CacheControl(); cacheControl.setPrivate( true ); cacheControl.setMaxAge( 0 ); cacheControl.setMustRevalidate( true ); response.cacheControl( cacheControl ); response = calculateContentDisposition( response, state ); return response.build(); }</code><technical_language>checking future.isDone() potentially situation do request content future.get() waiting for competition. a blocking operation. If request content for 1st page calling /content end-point for content is ready blocking request async requests for page. consider request 'first page' in regular instead of async mode, asuming 1st page is in cache - is ready want waste thread pool short-running tasks</technical_language>

Target:
@POST @Path( "{job_id}/content" ) public Response getContent( @PathParam( "job_id" ) String job_id ) throws IOException { UUID uuid = null; try { uuid = UUID.fromString( job_id ); } catch ( Exception e ) { logger.error( "Content: invalid UUID: " + job_id ); return get404(); } IPentahoAsyncExecutor executor = getExecutor(); if ( executor == null ) { return Response.serverError().build(); } final IPentahoSession session = PentahoSessionHolder.getSession(); Future<InputStream> future = executor.getFuture( uuid, session ); IAsyncReportState state = executor.getReportState( uuid, session ); if ( state == null ) { return get404(); } if( !AsyncExecutionStatus.FINISHED.equals( state.getStatus() ) ){ return Response.status( Response.Status.ACCEPTED ).build(); } InputStream input = null; try { input = future.get(); } catch ( Exception e ) { logger.error( "Error generating report", e ); return Response.serverError().build(); } executor.cleanFuture( uuid, session ); StreamingOutput stream = new StreamingOutputWrapper( input ); MediaType mediaType = null; Response.ResponseBuilder response = null; try { mediaType = MediaType.valueOf( state.getMimeType() ); response = Response.ok( stream, mediaType ); } catch ( Exception e ) { logger.error( "can't determine JAX-RS media type for: " + state.getMimeType() ); response = Response.ok( stream, state.getMimeType() ); } CacheControl cacheControl = new CacheControl(); cacheControl.setPrivate( true ); cacheControl.setMaxAge( 0 ); cacheControl.setMustRevalidate( true ); response.cacheControl( cacheControl ); response = calculateContentDisposition( response, state ); return response.build(); }