File: Asynchronous_HTTP.xml

package info (click to toggle)
resteasy 3.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 34,612 kB
  • sloc: java: 265,492; xml: 27,855; javascript: 405; jsp: 166; python: 101; sh: 15; sql: 3; makefile: 2
file content (143 lines) | stat: -rw-r--r-- 6,221 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<chapter id="Asynchronous_HTTP_Request_Processing">
   <title>Asynchronous HTTP Request Processing</title>
   <para>
      Asynchronous HTTP Request Processing is a relatively new technique that allows you to process a single HTTP
      request using non-blocking I/O and, if desired in separate threads. Some refer to it as COMET capabilities.
      The primary use case for Asynchronous HTTP is
      in the case where the client is polling the server for a delayed response. The usual example is an AJAX chat
      client where you want to push/pull from both the client and the server. These scenarios have the client blocking
      a long time on the server’s socket waiting for a new message. What happens in synchronous HTTP where the server is
      blocking on incoming and outgoing I/O is that you end up having a thread consumed per client connection.
      This eats up memory and valuable thread resources. Not such a big deal in 90% of applications (in fact using
      asynchronous processing may actually hurt your performance in most common scenarios), but when you start
      getting a lot of concurrent clients that are blocking like this, there’s a lot of wasted resources and your
      server does not scale that well.
   </para>
   <sect1>
      <title>Using the <code>@Suspended</code> annotation</title>
      <para>
         The JAX-RS 2.0 specification has added asynchronous HTTP support via two classes.  The <code>@Suspended</code> annotation,
         and AsyncResponse interface.
      </para>
      <para>
          Injecting an AsynchronousResponse as a parameter to your jax-rs methods tells RESTEasy that the HTTP request/response should be detached from the currently
         executing thread and that the current thread should not try to automatically process the response.
      </para>
      <para>
         The AsyncResponse is the callback object.
         The act of calling one of the resume() methods will cause a response to be sent back to the client and will also terminate the
         HTTP request. Here is an example of asynchronous processing:
      </para>
   
      <programlisting>
import javax.ws.rs.Suspend;
import javax.ws.rs.core.AsynchronousResponse;

@Path("/")
public class SimpleResource
{

   @GET
   @Path("basic")
   @Produces("text/plain")
   public void getBasic(@Suspended final AsyncResponse response) throws Exception
   {
      Thread t = new Thread()
      {
         @Override
         public void run()
         {
            try
            {
               Response jaxrs = Response.ok("basic").type(MediaType.TEXT_PLAIN).build();
               response.resume(jaxrs);
            }
            catch (Exception e)
            {
               response.resume(e);
            }
         }
      };
      t.start();
   }
}
      </programlisting>
      <para>
         AsyncResponse also has other methods to cancel the execution.  See javadoc for more details.
      </para>
      <para>
         <emphasis role="bold">NOTE:</emphasis> The old RESTEasy proprietary API for async http has been deprecated and may be removed as soon as RESTEasy 3.1.
         In particular, the RESTEasy @Suspend annotation is replaced by <classname>javax.ws.rs.container.Suspended</classname>, and
         <classname>org.jboss.resteasy.spi.AsynchronousResponse</classname> is replaced by
         <classname>javax.ws.rs.container.AsyncResponse</classname>. Note that @Suspended does not have a value field,
         which represented a timeout limit. Instead, <methodname>AsyncResponse.setTimeout()</methodname> may be called.
      </para>
   </sect1>
   <sect1>
      <title>Using Reactive return types</title>
      <para id="CompletionStage">
          The JAX-RS 2.1 specification adds support for declaring asynchronous resource methods by
          returning a <code>CompletionStage</code> instead of using the <code>@Suspended</code>
          annotation.
      </para>
      <para>
          Whenever a resource method returns a <code>CompletionStage</code>, it will be subscribed to,
          the request will be suspended, and only resumed when the <code>CompletionStage</code> is
          resolved either to a value (which is then treated as the return value for the method), or
          as an error case, in which case the exception will be processed as if it were thrown by the
          resource method.
      </para>
      <para>
          Here is an example of asynchronous processing using <code>CompletionStage</code>:
      </para>
      <programlisting>
import javax.ws.rs.Suspend;
import javax.ws.rs.core.AsynchronousResponse;

@Path("/")
public class SimpleResource
{

   @GET
   @Path("basic")
   @Produces("text/plain")
   public CompletionStage&lt;Response&gt; getBasic() throws Exception
   {
      final CompletableFuture&lt;Response&gt; response = new CompletableFuture&lt;&gt;();
      Thread t = new Thread()
      {
         @Override
         public void run()
         {
            try
            {
               Response jaxrs = Response.ok("basic").type(MediaType.TEXT_PLAIN).build();
               response.complete(jaxrs);
            }
            catch (Exception e)
            {
               response.completeExceptionally(e);
            }
         }
      };
      t.start();
      return response;
   }
}
     </programlisting>
     <note>
        <para>
           RESTEasy <link linkend="Reactive">supports more reactive types for asynchronous programming</link>.
        </para>
     </note>
   </sect1>
   <sect1>
      <title>Asynchronous filters</title>
      <para>
         It is possible to write <link linkend="Asynchronous_Filter">filters that also turn the request asynchronous</link>. 
         Whether or not filters turned the request asynchronous
         before execution of your method makes absolutely no difference to your method: it does not need to be declared asynchronous in
         order to function as specified. Synchronous methods and asynchronous methods will work as specified by the spec.
      </para>
    </sect1>
</chapter>