users@jax-rs-spec.java.net

[jax-rs-spec users] Re: NIO draft

From: Santiago Pericasgeertsen <santiago.pericasgeertsen_at_oracle.com>
Date: Tue, 20 Oct 2015 09:29:44 -0400

Markus,

 I’ve seen people doing exactly what you say it’s not needed. These are likely the same developers using StreamingOutput today —I don’t think it is the majority, but I don’t think it is the majority that need NIO. As I responded to an earlier message to Bill, this is only part of the story. We do need to explore NIO for at least MBR/MBW’s.

 Do you have some cycles to explore that use case?

— Santiago

> On Oct 19, 2015, at 4:55 PM, Markus KARG <markus_at_headcrashing.eu> wrote:
>
> From my point of view, the main driver for NIO is to massively increase server scalability, which typically is achieved by using less threads, as the amount of threads produces unnecessary overhead for the OS and JVM. Blocking-IO currently demands on thread per request. NIO allows one thread per thousands of requests. The typical NIO solution hence is a container that has a single thread per LAN card. So the actual showstopper in the existing JAX-RS API is not what your examples showcase, but in fact it is:
>
> * WriterInterceptorContext.getOutputStream() --> Uses blocking OutputStream, but must return a non-blocking WriteableByteChannel.
> * ReaderInterceptorContext.getInputStream() --> Uses blocking InputStream, but must return a non-blocking ReaderByteChannel.
> * ContainerRequestContext.get/setEntityStream() --> Uses blocking InputStream, but must return a non-blocking ReaderByteChannel.
> * ContainerResponseContext.get/setEntityStream() --> Uses blocking OutputStream, but must return a non-blocking WriteableByteChannel.
>
> Using a *Channel instead of a *Stream a filter / interceptor can detect potential blocks of the container's LAN card, skip the blocking call, and instead file the request to try again later using CompletableFuture in conjunction with the Java EE container's managed executor service or any other application-wide executor. As you know, this is what typically is called a "multi-fiber" architecture, which is one of the most effective ways to utility NIO on the server side.
>
> In my eyes that scenario (allowing the JAX-RS container to use one single thread per LAN card by replacing *Stream by *Channel, so the thread can do any other work if the LAN card would block) is far more important than the scenarios covered by the examples found in the proposal. In fact, any kind of NIO within the resource class and / or client API should not be part of the API, as it simply is a task of the JAX-RS implementation to leverage NIO within its own source code to prevent blocking at request / response handling. I do not see any need to expose NIO to the application programmer here.
>
> -Markus
>
>
> From: Santiago Pericasgeertsen [mailto:santiago.pericasgeertsen_at_oracle.com <mailto:santiago.pericasgeertsen_at_oracle.com>]
> Sent: Montag, 12. Oktober 2015 16:30
> To: jsr370-experts_at_jax-rs-spec.java.net <mailto:jsr370-experts_at_jax-rs-spec.java.net>
> Subject: Drafts for Rx, NIO and SSE
>
> Dear Experts,
>
> My apologies for sending all these drafts in one shot, but I feel we need to start making progress quickly if we want to produce an EDR in a few months.
>
> The following pull request [1] includes proposals for Rx, NIO and SSE. Let me point you to the examples to get you started:
>
> (1) Rx:
>
> https://github.com/spericas/api/blob/master/jaxrs-api/src/test/java/javax/ws/rs/core/RxClientTest.java <https://github.com/spericas/api/blob/master/jaxrs-api/src/test/java/javax/ws/rs/core/RxClientTest.java>
>
> This is an extension to our Client API that integrates with the CompletableFuture API in JDK 8 (note that CompletionStage is a super type of CompletableFuture). The proposal is extensible and can use other APIs similar to CompletableFuture —see the optional parameter to the rx() method for that purpose. The spec will only mandate support for CompletableFuture, but implementations are free to provide support for other APIs, such as RxJava.
>
> (2) NIO:
>
> https://github.com/spericas/api/blob/master/examples/src/main/java/jaxrs/examples/nio/FileResource.java <https://github.com/spericas/api/blob/master/examples/src/main/java/jaxrs/examples/nio/FileResource.java>
> https://github.com/spericas/api/blob/master/examples/src/main/java/jaxrs/examples/nio/FileResourceClient.java <https://github.com/spericas/api/blob/master/examples/src/main/java/jaxrs/examples/nio/FileResourceClient.java>
>
> On the server side, the proposal follows the pattern set by StreamingOutput, but of course using lambdas this time around. As you know, Servlet already supports NIO, but with a completely different API.
>
> (3) SSE:
>
> https://github.com/mpotociar/api/tree/master/examples/src/main/java/jaxrs/examples/sse <https://github.com/mpotociar/api/tree/master/examples/src/main/java/jaxrs/examples/sse>
>
> Note that like in NIO, there are proposed extensions to both the Client and Server APIs for SSE.
>
> I understand that this is a lot to digest, so feel free to start new e-mail threads to discuss each one independently. I just felt it was important to start all these discussions ASAP.
>
> — Santiago
>
> [1] https://github.com/jax-rs/api/pulls <https://github.com/jax-rs/api/pulls>