jsr370-experts@jax-rs-spec.java.net

Re: NIO draft

From: Bill Burke <bburke_at_redhat.com>
Date: Tue, 20 Oct 2015 10:20:44 -0400

I'm still for creating NIO-based MBW/MBRs and the StreamingOutput
style...BUT...

My biggest concern is that this we're creating something that a)
developers won't use or b) will use thinking they are going to gain this
big performance benefit. coding NIO handlers is much more complicated
than the BIO-based java.io equivalent. I only looked a couple years
ago, but I didn't find any XML or JSON NIO-based parsers.

JAX-RS already can do async HTTP with BIO. Meaning, you can have a
writer thread if you want. So, is NIO-based JAX-RS really worth it?

Just throwing this out there to think about. Since I'm getting old and
have been doing Java EE spec stuff for 10 years now, I get a bit cynical...


On 10/20/2015 9:29 AM, Santiago Pericasgeertsen wrote:
> 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
>> <mailto: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]
>> *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
>> 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/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
>> 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
>

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com