jsr340-experts@servlet-spec.java.net

[jsr340-experts] Re: Proposal for WebSocket to be part of JSR 340

From: Richard <richardhightower_at_gmail.com>
Date: Wed, 5 Oct 2011 11:22:11 -0700

I am going to go for short sentences to aid in my clarity.

The proposal does not advocate a blocking API for handler threads.

The proposal does not present an API that blocks and only allows one client conversation to happen at a time. The engine can handle as many conversations as your resources will allow.

WebSockets is a bidirectional protocol so communication once established by the client can happen both ways and is inherently bidirectional and asynchronous.

The proposal advocates using handlers to handle requests from clients. The lifecycle of the handler (WebSocketHandler) is the same duration as the WebSocket conversation. The handler methods are ways for the engine to notify that:
 WebSocket conversation has started.
 WebSocket conversation ended
 An incoming text message is coming in
 An incoming binary message is coming in

A WebSocket conversation can have many, many messages. The engine will assemble the WebSocket frames and from the app users perspective they are dealing with an input stream or reader.

Once a handler method finishes executing it does not tie up a thread. It does not block. The thread that was servicing that handler method could be used to service other methods. Blocking Communication to multiple clients NEVER happens. It was never proposed.

Handler methods should not do things that block. It should return quickly. A handler that did something that blocked would be like a Servlet that blocked with similar ramifications and similar handling of said ramifications.

The handler can use the WebContext.start method to run one or more background Tasks (Runnables). Remember with WebSockets both sides of the wire can initiate sending messages. It is not request/response like Servlets. These Tasks are running in their own threads and may at times be sleeping or waiting or blocked. They are not blocking other sending threads. They are NOT blocking the engine from handling messages from originating from the client. Messages can be sent bidirectionally and asynchronously always. The ability to have these Tasks is inherently ingrained in the WebSocket mindset, i.e., the server can initiate calls to the client. The server must be able to send messages so these tasks must live outside of the initial request scope by design.


The WebSocketContext also has a lifecycle of the websocket conversation. Since multiple tasks can send messages to the same client over the same client connection, you need a way to ensure that two messages are not being sent at the same time. This is not a new concept. You don't want stream / frame corruption. Any WebSocket proposal must have this coordination. This has as much to do with the current state and direction of WebSockets as anything else. You can't intermix frames from multiple messages. If / when WebSocket mux is defined this may change but beauty of this API is that blocking / muxing is abstracted from the app developer.


Is this a quick and dirty?

No. A simple API does not always imply quick and dirty. Just as a complex API does not imply a good design. An API should be as simple as possible always. The hard part should always be the engine. That is why you guys get the big bucks. :)

There is nothing unscalable or unseemly about this API.


If you are going to have a frame and/or filter API for WebSockets which I STRONGLY do not recommend until a later Servlet spec since by that time there will be WebSocket extensions written. (doing it before is like building a dog house before you decide what kind of dog you want. Great Dane? Poodle?) Then it should really be a WebSocket SPI. The WebSocket API should be at a higher abstraction. I propose a split API SPI. For JSR 340, we 100 percent need it not having would be a big mistake and an SPI if we have enough time.

SPI is a nice to have maybe. An API is a must.

I did not copy edit this much. It is more stream of thought.






Sent from my iPad

On Oct 5, 2011, at 8:34 AM, Rick Hightower <richardhightower_at_gmail.com> wrote:

>
> RE: Ok, this is too long for me to fully comment in only one reply, but:
> - There is indeed a need to amend the JSR to encompass a separate
> websocket API. I am rather ok with that.
>
> +1
>
> RE: So I am +1 with attempting to do websockets as part of this JSR,
>
> +1
>
> Those are the two things I agree with the most about your response. :)
> The rest are just sorting out the details.
>
>
> But some short responses below.
>
>
>
> - Websocket is labelled as the next big thing. To be honest, I think it
> has serious issues, especially the unlimited frame size. It means no
> corruption detection for missing data, and the API becomes exponentially
> more complex.
>
> *** I don't agree, but sort of a moot point if we are going to add support.
>
> - Websocket indeed needs some stream based API, rather than something
> based on byte[], mostly due to the unlimited size of frames.
>
> *** Agree strongly with this.
>
> - What you propose is a blocking API equivalent to Servlet 1.0 for HTTP,
> and this is not acceptable. For the most immediate issue, you can look
> at Rajiv's first proposal which adds non blocking to a stream API.
>
>
> *** Fundamentally, I don't agree, but would love to see Rajiv's proposal. I went through the mailing, list and somehow must have missed it. Where can I find it?
>
> *** My understanding is.... in order to stop frame corruption, you can't really have two threads writing to the same client at the same time. At some level something has to coordinate threads writing to the same client. This is not a forever block, but a block used to coordinate message sending. Just imagine two clients trying to write to the same TCP/IP connection. You can't have half a message from one thread intermixed with half a message from a second thread, intermixed with a third and so on.
>
> *** Please correct my understanding if it is flawed. I will continue to think about this as well and look at Rajiv's proposal.
>
>
>
> - No filtering is a problem, it does not sound good to label it as "if
> needed". I simply don't understand how it would not be needed
> immediately.
>
> *** Give an example where it would be used. To implement what?
> People use TCP/IP all the time, is there a packet filter in the servlet spec so that
> developers can inspect packets? No. WebSocket frames are at a very low level.
> I am not saying never. I am saying it does not have to be in the first release.
> If you feel it is a must, I would rather have it then not have WebSocket.
> I just think it is a distraction.
>
>
> - The portion on lock design for output based on hijacking close()
> methods from streams is not right. The goal is to use one thread to
> service as many clients as possible [using a non blocking API], not to
>
> ** The threading model is split. The handlers are handled like Servlets.
> It is non-blocking. It is only the writing that needs sync and the writing can and most likely will happen in another thread.
>
> use multiple threads to service many clients using a blocking API [if it
> was non blocking, then this model is also wrong].
>
> ** I would agree which is why it was not proposed.
>
> A model where multiple
> async threads are supposed to wait on locks is wrong, because the
> threads will soon all be waiting on slow clients.
>
> ** see earlier comments on frame corruption when writing to the same client.
>
> - I think integration with Servlet API needs something. There is no
> callback at all here, on purpose, but I don't agree with that choice.
>
> ** What would the callback do? Come up with a use case for it. I can't think of any.
>
> So I am +1 with attempting to do websockets as part of this JSR, but -1
> on doing a quick and dirty API for it (it needs to have at least the
> same level of non blocking IO functionality as its HTTP counterpart,
> plus likely some filtering).
>
> ** Running my monkeys to school. Ran out of time for a longer response, but it will be there. :)
>
> On Wed, Oct 5, 2011 at 5:17 AM, Remy Maucherat <rmaucher_at_redhat.com> wrote:
> On Wed, 2011-10-05 at 02:38 -0700, Rick Hightower wrote:
> > The purpose of this proposal is to table the needs for WebSocket, and
> > state emphatically that WebSocket needs to be in JSR-340. WebSocket
> > support in JSR 340 needs a simple streaming interface. Two small
> > interfaces and one additional method to ServletRequest is all that is
> > proposed. This WebSocket package is at the same level of abstraction
> > as the Servlet API but geared toward WebSockets.
>
> - Websocket is labelled as the next big thing. To be honest, I think it
> has serious issues, especially the unlimited frame size. It means no
> corruption detection for missing data, and the API becomes exponentially
> more complex.
> - Websocket indeed needs some stream based API, rather than something
> based on byte[], mostly due to the unlimited size of frames.
> - What you propose is a blocking API equivalent to Servlet 1.0 for HTTP,
> and this is not acceptable. For the most immediate issue, you can look
> at Rajiv's first proposal which adds non blocking to a stream API.
> - No filtering is a problem, it does not sound good to label it as "if
> needed". I simply don't understand how it would not be needed
> immediately.
> - The portion on lock design for output based on hijacking close()
> methods from streams is not right. The goal is to use one thread to
> service as many clients as possible [using a non blocking API], not to
> use multiple threads to service many clients using a blocking API [if it
> was non blocking, then this model is also wrong]. A model where multiple
> async threads are supposed to wait on locks is wrong, because the
> threads will soon all be waiting on slow clients.
> - I think integration with Servlet API needs something. There is no
> callback at all here, on purpose, but I don't agree with that choice.
>
> So I am +1 with attempting to do websockets as part of this JSR, but -1
> on doing a quick and dirty API for it (it needs to have at least the
> same level of non blocking IO functionality as its HTTP counterpart,
> plus likely some filtering).
>
> --
> Remy Maucherat <rmaucher_at_redhat.com>
> Red Hat Inc
>
>
>
>
> --
> Rick Hightower
> (415) 968-9037
> Profile
>