<?xml version="1.0"?>
<!--

    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

    Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.

    The contents of this file are subject to the terms of either the GNU
    General Public License Version 2 only ("GPL") or the Common Development
    and Distribution License("CDDL") (collectively, the "License").  You
    may not use this file except in compliance with the License.  You can
    obtain a copy of the License at
    http://glassfish.java.net/public/CDDL+GPL_1_1.html
    or packager/legal/LICENSE.txt.  See the License for the specific
    language governing permissions and limitations under the License.

    When distributing the software, include this License Header Notice in each
    file and include the License file at packager/legal/LICENSE.txt.

    GPL Classpath Exception:
    Oracle designates this particular file as subject to the "Classpath"
    exception as provided by Oracle in the GPL Version 2 section of the License
    file that accompanied this code.

    Modifications:
    If applicable, add the following below the License Header, with the fields
    enclosed by brackets [] replaced by your own identifying information:
    "Portions Copyright [year] [name of copyright owner]"

    Contributor(s):
    If you wish your version of this file to be governed by only the CDDL or
    only the GPL Version 2, indicate your decision by adding "[Contributor]
    elects to include this software in this distribution under the [CDDL or GPL
    Version 2] license."  If you don't indicate a single choice of license, a
    recipient has the option to distribute your version of this file under
    either the CDDL, the GPL Version 2 or to extend the choice of license to
    its licensees as provided above.  However, if you add GPL Version 2 code
    and therefore, elected the GPL Version 2 license, then the option applies
    only if the new code is made subject to such option by the copyright
    holder.

-->
<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents;]>
<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="async">
    <title>Asynchronous Services and Clients</title>
    <para>
        This chapter describes the usage of asynchronous API on the client and server side. The term <emphasis>async</emphasis>
        will be sometimes used interchangeably with the term <emphasis>asynchronous</emphasis> in this chapter.
    </para>
    <section>
        <title>Asynchronous Server API</title>
        <para>
            Request processing on the server works by default in a synchronous processing mode, which means that a client
            connection of a request is processed in a single I/O container thread. Once the thread processing the request
            returns to the I/O container, the container can safely assume that the request processing is finished and that
            the client connection can be safely released including all the resources associated with the connection. This model
            is typically sufficient for processing of requests for which the processing resource method execution takes
            a relatively short time. However, in cases where a resource method execution is known to take a long time to compute
            the result, server-side asynchronous processing model should be used. In this model, the association between a
            request processing thread and client connection is broken. I/O container that handles incoming request may no longer
            assume that a client connection can be safely closed when a request processing thread returns. Instead a facility for
            explicitly suspending, resuming and closing client connections needs to be exposed.
            Note that the use of server-side asynchronous processing model will not improve the request processing time perceived
            by the client. It will however increase the throughput of the server, by releasing the
            initial request processing thread back to the I/O container while the request may still be waiting in a queue for
            processing or the processing may still be running on another dedicated thread. The released I/O container thread
            can be used to accept and process new incoming request connections.
        </para>
        <para>
            The following example shows a simple asynchronous resource method defined using the new JAX-RS async API:
            <example>
                <title>Simple async resource</title>
                <programlisting language="java" linenumbering="numbered">@Path("/resource")
public class AsyncResource {
    @GET
    public void asyncGet(@Suspended final AsyncResponse asyncResponse) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                // ... very expensive operation
            }
        }).start();
    }
}</programlisting>
            </example>
            In the example above, a resource <literal>AsyncResource</literal>
            with one <literal>GET</literal> method <literal>asyncGet</literal> is defined. The <literal>asyncGet</literal> method
            injects a JAX-RS &jaxrs.container.AsyncResponse; instance using a JAX-RS &jaxrs.container.Suspended; annotation.
            Please note that &lit.jaxrs.container.AsyncResponse; must be injected by the &lit.jaxrs.container.Suspended;
            annotation and not by &jaxrs.core.Context; as &lit.jaxrs.container.Suspended; does not only inject response but also
            says that the method is executed in the asynchronous mode. By the &lit.jaxrs.container.AsyncResponse; parameter into
            a resource method we tell the Jersey runtime that the method is supposed to be invoked using the asynchronous
            processing mode, that is the client connection should not be automatically closed by the underlying I/O container
            when the method returns. Instead, the injected &lit.jaxrs.container.AsyncResponse; instance (that represents the
            suspended client request connection) will be used to explicitly send the response back to the client using some other
            thread. In other words, Jersey runtime knows that when the <literal>asyncGet</literal> method completes, the response
            to the client may not be ready yet and the processing must be suspended and wait to be explictly resumed with a
            response once it becomes available. Note that the method <literal>asyncGet</literal> returns <literal>void</literal>
            in our example. This is perfectly valid in case of an asynchronous JAX-RS resource method, even for a &jaxrs.GET;
            method, as the response is never returned directly from the resource method as its return value. Instead, the response
            is later returned using &lit.jaxrs.container.AsyncResponse; instance as it is demonstrated in the example. The
            <literal>asyncGet</literal> resource method starts a new thread and exits from the method. In that state the
            request processing is suspended and the container thread (the one which entered the resource method) is returned back
            to the container's thread pool and it can process other requests. New thread started in the resource method may
            execute an expensive operation which might take a long time to finish. Once a result is ready it is resumed using
            the <literal>resume()</literal> method on the &lit.jaxrs.container.AsyncResponse; instance.
            The resumed response is then processed in the new thread by Jersey in a same way as any other synchronous response,
            including execution of filters and interceptors, use of exception mappers as necessary and sending the response
            back to the client.
        </para>
        <para>
            It is important to note that the asynchronous response (<literal>asyncResponse</literal> in the example)
            does not need to be resumed from the thread started from the resource method. The asynchronous
            response can be resumed even from different request processing thread as it is shown in the
            the example of the &jaxrs.container.AsyncResponse; javadoc. In the javadoc example the
            async response suspended from the &lit.http.GET; method is resumed later on from
            the &lit.http.POST; method. The suspended async response is passed between requests using
            a static field and is resumed from the other resource method running on a different request processing thread.
        </para>
        <para>
            Imagine now a situation when there is a long delay between two requests and you would not like to let
            the client wait for the response "forever" or at least for an unacceptable long time. In asynchronous processing
            model, occurrences of such situations should be carefully considered with client connections not being automatically
            closed when the processing method returns and the response needs to be resumed explicitly based on an event that
            may actually even never happen. To tackle these situations asynchronous <emphasis>timeouts</emphasis> can be used.
        </para>
        <para>
            The following example shows the usage of timeouts:
            <example>
                <title>Simple async method with timeout</title>
                <programlisting language="java" linenumbering="numbered">@GET
public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
    asyncResponse.setTimeoutHandler(new TimeoutHandler() {

        @Override
        public void handleTimeout(AsyncResponse asyncResponse) {
            asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
                    .entity("Operation time out.").build());
        }
    });
    asyncResponse.setTimeout(20, TimeUnit.SECONDS);

    new Thread(new Runnable() {

        @Override
        public void run() {
            String result = veryExpensiveOperation();
            asyncResponse.resume(result);
        }

        private String veryExpensiveOperation() {
            // ... very expensive operation that typically finishes within 20 seconds
        }
    }).start();
}</programlisting>
            </example>
            By default, there is no timeout defined on the suspended &lit.jaxrs.container.AsyncResponse; instance.
            A custom timeout and timeout event handler may be defined using <literal>setTimeoutHandler(TimeoutHandler)</literal>
            and <literal>setTimeout(long, TimeUnit)</literal> methods. The <literal>setTimeoutHandler(TimeoutHandler)</literal>
            method defines the handler that will be invoked when timeout is reached. The handler resumes the response with the
            response code 503 (from Response.Status.<literal>SERVICE_UNAVAILABLE</literal>).
            A timeout interval can be also defined without specifying a custom timeout handler (using just the
            <literal>setTimeout(long, TimeUnit)</literal> method).
            In such case the default behaviour of Jersey runtime is to throw a <literal>ServiceUnavailableException</literal>
            that gets mapped into 503, "Service Unavailable" HTTP error response, as defined by the JAX-RS specification.
        </para>

        <section>
            <title>Asynchronous Server-side Callbacks</title>
            <para>
                As operations in asynchronous cases might take long time and they are not always finished within
                a single resource method invocation, JAX-RS offers facility to register callbacks to be invoked
                based on suspended async response state changes. In Jersey you can register two JAX-RS callbacks:
                <itemizedlist>
                    <listitem><simpara>
                        &jaxrs.container.CompletionCallback; that is executed when request finishes or fails, and
                    </simpara></listitem>
                    <listitem><simpara>
                        &jaxrs.container.ConnectionCallback; executed when a connection to a client is closed or lost.
                    </simpara></listitem>
                </itemizedlist>
                <example>
                    <title>CompletionCallback example</title>
                    <programlisting language="java" linenumbering="numbered">@Path("/resource")
public class AsyncResource {
    private static int numberOfSuccessResponses = 0;
    private static int numberOfFailures = 0;
    private static Throwable lastException = null;

    @GET
    public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
        asyncResponse.register(new CompletionCallback() {
            @Override
            public void onComplete(Throwable throwable) {
                if (throwable == null) {
                    // no throwable - the processing ended successfully
                    // (response already written to the client)
                    numberOfSuccessResponses++;
                } else {
                    numberOfFailures++;
                    lastException = throwable;
                }
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                // ... very expensive operation
            }
        }).start();
    }
}</programlisting>
                </example>
                A completion callback is registered using <literal>register(...)</literal> method
                on the &lit.jaxrs.container.AsyncResponse; instance. A registered completion callback is bound only
                to the response(s) to which it has been registered. In the example the &lit.jaxrs.container.CompletionCallback;
                is used to calculate successfully processed responses, failures and to store last exception. This is only a
                simple case demonstrating the usage of the callback. You can use completion callback to release the resources,
                change state of internal resources or representations or handle failures. The method has an argument
                <literal>Throwable</literal> which is set only in case of an error. Otherwise the parameter
                will be <literal>null</literal>, which means that the response was successfully written. The callback is executed
                only after the response is written to the client (not immediately after the response is resumed).
            </para>
            <para>
                The &lit.jaxrs.container.AsyncResponse; <literal>register(...)</literal> method is overloaded and offers options
                to register a single callback as an <literal>Object</literal> (in the example), as a <literal>Class</literal> or
                multiple callbacks using varags.
            </para>
            <para>
                As some async requests may take long time to process the client may decide to terminate it's connection to the
                server before the response has been resumed or before it has been fully written to the client. To deal with these
                use cases a &lit.jaxrs.container.ConnectionCallback; can be used. This callback will be executed only if the
                connection was prematurely terminated or lost while the response is being written to the back client. Note that
                this callback will not be invoked when a response is written successfully and the client connection is closed
                as expected. See javadoc of &jaxrs.container.ConnectionCallback; for more information.
            </para>
        </section>

        <section xml:id="chunked-output">
            <title>Chunked Output</title>
            <para>Jersey offers a facility for sending response to the client in multiple more-or-less independent chunks using a
                <emphasis>chunked output</emphasis>. Each response chunk usually takes some (longer) time to prepare before
                sending it to the client. The most important fact about response chunks is that you want
                to send them to the client immediately as they become available without waiting for the remaining chunks to become
                available too. The first bytes of each chunked response consists of the HTTP headers that are sent to the client.
                As noted above, the entity of the response is then sent in chunks as they become available.
                Client knows that the response is going to be chunked, so it reads each chunk of the response separately,
                processes it, and waits for more chunks to arrive on the same connection. After some time, the server generates
                another response chunk and send it again to the client. Server keeps on sending response chunks until
                it closes the connection after sending the last chunk when the response processing is finished.
            </para>
            <para>
                In Jersey you can use &jersey.server.ChunkedOutput; to send response to a client in chunks. Chunks are strictly
                defined pieces of a response body can be marshalled as a separate entities using Jersey/JAX-RS
                &jaxrs.ext.MessageBodyWriter; providers. A chunk can be String, Long or JAXB bean serialized to XML or JSON or
                any other dacustom type for which a &lit.jaxrs.ext.MessageBodyWriter; is available.
            </para>
            <para>
                The resource method
                that returns &lit.jersey.server.ChunkedOutput; informs the Jersey runtime that the response will be chunked
                and that the processing works asynchronously as such. You do not need to inject
                &lit.jaxrs.container.AsyncResponse; to start the asynchronous processing mode in this case.
                Returning a &lit.jersey.server.ChunkedOutput; instance from the method is enough to indicate the asynchronous
                processing. Response headers will be sent to a client when the resource method returns and the client will wait
                for the stream of chunked data which you will be able to write from different thread using the same
                &lit.jersey.server.ChunkedOutput; instance returned from the resource method earlier. The following example
                demonstrates this use case:
                <example>
                    <title>ChunkedOutput example</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[@Path("/resource")
public class AsyncResource {
    @GET
    public ChunkedOutput<String> getChunkedResponse() {
        final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class);

        new Thread() {
            public void run() {
                try {
                    String chunk;

                    while ((chunk = getNextString()) != null) {
                        output.write(chunk);
                    }
                } catch (IOException e) {
                    // IOException thrown when writing the
                    // chunks of response: should be handled
                } finally {
                    output.close();
                        // simplified: IOException thrown from
                        // this close() should be handled here...
                }
            }
        }.start();

        // the output will be probably returned even before
        // a first chunk is written by the new thread
        return output;
    }

    private String getNextString() {
        // ... long running operation that returns
        //     next string or null if no other string is accessible
    }
}]]></programlisting>
                </example>
                The example above defines a &lit.http.GET; method that returns a &lit.jersey.server.ChunkedOutput; instance.
                The generic type of &lit.jersey.server.ChunkedOutput; defines the chunk types (in this case chunks are Strings).
                Before the instance is returned a new thread is started that writes individual chunks into
                the chunked output instance named <literal>output</literal>. Once the original
                thread returns from the resource method, Jersey runtime writes headers to the container response but does not
                close the client connection yet and waits for the response data to be written to the chunked
                <literal>output</literal>.
                New thread in a loop calls the method <literal>getNextString()</literal> which returns a
                next String or &lit.null; if no other String exists (the method could for example load latest data
                from the database). Returned Strings are written to the chunked <literal>output</literal>. Such a written
                chunks are internally written to the container response and client can read them. At the end the
                chunked output is closed which determines the end of the chunked response. Please note that you must close
                the output explicitly in order to close the client connection as Jersey does not implicitly know when
                you are finished with writing the chunks.
            </para>
            <para>
                A chunked output can be processed also from threads created from another request as it is explained in the
                sections above. This means that one resource method may e.g. only return a &lit.jersey.server.ChunkedOutput;
                instance and other resource method(s) invoked from another request thread(s) can write data into the chunked
                output and/or close the chunked response.
            </para>
        </section>
    </section>
    <section>
        <title>Client API</title>
        <para>The client API supports asynchronous processing too. Simple usage of asynchronous client API is shown in the
        following example:
            <example>
                <title>Simple client async invocation</title>
<programlisting language="java" linenumbering="numbered"><![CDATA[final AsyncInvoker asyncInvoker = target().path("http://example.com/resource/")
        .request().async();
final Future<Response> responseFuture = asyncInvoker.get();
System.out.println("Request is being processed asynchronously.");
final Response response = responseFuture.get();
    // get() waits for the response to be ready
System.out.println("Response received.");]]></programlisting>
            </example>
            The difference against synchronous invocation is that the http method call <literal>get()</literal>
            is not called on &jaxrs.client.SyncInvoker; but on &jaxrs.client.AsyncInvoker;. The
            &lit.jaxrs.client.AsyncInvoker; is returned from the call of method
            <literal>Invocation.Builder.async()</literal> as shown above. &lit.jaxrs.client.AsyncInvoker;
            offers methods similar to &lit.jaxrs.client.SyncInvoker; only these methods do not return a response
            synchronously. Instead a <literal>Future&lt;...&gt;</literal> representing response data is returned.
            These method calls also return immediately without waiting for the actual request to complete.
            In order to get the response of the invoked <literal>get()</literal> method, the
            <literal>responseFuture.get()</literal> is invoked which waits for the response to be finished
            (this call is blocking as defined by the Java SE <literal>Future</literal> contract).
        </para>
        <para>
            Asynchronous Client API in JAX-RS is fully integrated in the fluent JAX-RS Client API flow, so that
            the async client-side invocations can be written fluently just like in the following example:
            <example>
                <title>Simple client fluent async invocation</title>
                <programlisting language="java" linenumbering="numbered"><![CDATA[final Future<Response> responseFuture = target().path("http://example.com/resource/")
        .request().async().get();]]></programlisting>
            </example>
        </para>

        <para>
            To work with asynchronous results on the client-side, all standard <literal>Future</literal> API facilities
            can be used. For example, you can use the <literal>isDone()</literal> method
            to determine whether a response has finished to avoid the use of a blocking call to <literal>Future.get()</literal>.
        </para>

        <section>
            <title>Asynchronous Client Callbacks</title>
            <para>Similarly to the server side, in the client API you can register asynchronous callbacks too. You can use
                these callbacks to be notified when a response arrives instead of waiting for the
                response on <literal>Future.get()</literal> or checking the status by <literal>Future.isDone()</literal> in
                a loop.
                A client-side asynchronous invocation callback can be registered as shown in the following example:
                <example>
                    <title>Client async callback</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[final Future<Response> responseFuture = target().path("http://example.com/resource/")
        .request().async().get(new InvocationCallback<Response>() {
            @Override
            public void completed(Response response) {
                System.out.println("Response status code "
                        + response.getStatus() + " received.");
            }

            @Override
            public void failed(Throwable throwable) {
                System.out.println("Invocation failed.");
                throwable.printStackTrace();
            }
        });]]></programlisting>
                </example>

                The registered callback is expected to implement the &jaxrs.client.InvocationCallback; interface that defines
                two methods.
                First method <literal>completed(Response)</literal> gets invoked when an invocation successfully
                finishes. The result response is passed as a parameter to the callback method. The second method
                <literal>failed(Throwable)</literal> is invoked in case the invocation fails and the exception describing
                the failure is passed to the method as a parameter. In this case since the callback generic type is
                &lit.jaxrs.core.Response;, the <literal>failed(Throwable)</literal> method would  only invoked in case
                the invocation fails because of an internal client-side processing error. It would not be invoked
                in case a server responds with an HTTP error code, for example if the requested resource
                is not found on the server and HTTP <literal>404</literal> response code is returned. In such case
                <literal>completed(Response)</literal> callback method would be invoked and the response passed to the method
                would contain the returned error response with HTTP <literal>404</literal> error code. This is a special
                behavior in case the generic callback return type is &lit.jaxrs.core.Response;. In the next example an
                exception is thrown (or <literal>failed(Throwable)</literal> method on the invocation callback is invoked)
                even in case a non-<literal>2xx</literal> HTTP error code is returned.
            </para>
            <para>
                As with the synchronous client API, you can retrieve the response entity as a Java type directly without
                requesting a &lit.jaxrs.core.Response; first. In case of an &lit.jaxrs.client.InvocationCallback;, you need
                to set its generic type to the expected response entity type instead of using the &lit.jaxrs.core.Response;
                type as demonstrated in the example below:
                <example>
                    <title>Client async callback for specific entity</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[final Future<String> entityFuture = target().path("http://example.com/resource/")
        .request().async().get(new InvocationCallback<String>() {
            @Override
            public void completed(String response) {
                System.out.println("Response entity '" + response + "' received.");
            }

            @Override
            public void failed(Throwable throwable) {
                System.out.println("Invocation failed.");
                throwable.printStackTrace();
            }
        });
System.out.println(entityFuture.get());]]></programlisting>
                </example>
                Here, the generic type of the invocation callback information is used to unmarshall the HTTP response content
                into a desired Java type.
            </para>
            <important>
                <para>
                    Please note that in this case the method <literal>failed(Throwable throwable)</literal> would be invoked even
                    for cases when a server responds with a non HTTP-<literal>2xx</literal> HTTP error code. This is because in this
                    case the user does not have any other means of finding out that the server returned an error response.
                </para>
            </important>
        </section>

        <section>
            <title>Chunked input</title>
            <para>
                In an <link linkend="chunked-output">earlier section</link> the &lit.jersey.server.ChunkedOutput; was
                described. It was shown how to use a chunked output on the server. In order to read chunks on the client the
                &jersey.client.ChunkedInput; can be used to complete the story.
            </para>
            <para>
                You can, of course, process input on the client as a standard input stream but if you would like to
                leverage Jersey infrastructure to provide support of translating message chunk data into Java types
                using a &lit.jersey.client.ChunkedInput; is much more straightforward. See the usage of the
                &lit.jersey.client.ChunkedInput; in the following example:

                <example>
                    <title>ChunkedInput example</title>
                    <programlisting language="java" linenumbering="numbered"><![CDATA[final Response response = target().path("http://example.com/resource/")
        .request().get();
final ChunkedInput<String> chunkedInput =
        response.readEntity(new GenericType<ChunkedInput<String>>() {});
String chunk;
while ((chunk = chunkedInput.read()) != null) {
    System.out.println("Next chunk received: " + chunk);
}
]]></programlisting>
                </example>

                The response is retrieved in a standard way from the server. The entity is read as a
                &lit.jersey.client.ChunkedInput; entity. In order to do that the &jaxrs.core.GenericEntity; is used to preserve
                a generic information at run time. If you would not use &lit.jaxrs.core.GenericEntity;, Java language generic type
                erasure would cause that the generic information would get lost at compile time and an exception would be thrown
                at run time complaining about the missing chunk type definition.
            </para>
            <para>
                In the next lines in the example, individual chunks are being read from the response. Chunks can come with some
                delay, so they will be written to the console as they come from the server. After receiving last chunk the
                &lit.null; will be returned from the <literal>read()</literal> method. This will mean that the server has sent
                the last chunk and closed the connection. Note that the <literal>read()</literal> is a blocking operation and the
                invoking thread is blocked until a new chunk comes.
            </para>
            <para>
                Writing chunks with &lit.jersey.server.ChunkedOutput; is simple, you only call method <literal>write()</literal>
                which writes exactly one chunk to the output. With the input reading it is slightly more complicated. The
                &lit.jersey.client.ChunkedInput; does not know how to distinguish chunks in the byte stream unless being told by
                the developer. In order to define custom chunks boundaries,
                the &lit.jersey.client.ChunkedInput; offers possibility to register a &jersey.client.ChunkParser; which
                reads chunks from the input stream and separates them. Jersey provides several chunk parser implementation and
                you can implement your own parser to separate your chunks if you need. In our example above the default parser
                provided by Jersey is used that separates chunks based on presence of a <literal>\r\n</literal> delimiting
                character sequence.
            </para>
            <para>
                Each incoming input stream is firstly parsed by the &lit.jersey.client.ChunkParser;, then each chunk is processed
                by the proper &jaxrs.ext.MessageBodyReader;.
                You can define the media type of chunks to aid the selection of a proper &lit.jaxrs.ext.MessageBodyReader; in
                order to read chunks correctly into the requested entity types (in our case into Strings).
            </para>
        </section>
    </section>
</chapter>
