jsr356-experts@websocket-spec.java.net

[jsr356-experts] Re: Session.getCloseStatus isActive and getInactiveTime

From: Bill Wigger <wigger_at_us.ibm.com>
Date: Fri, 10 Aug 2012 11:10:28 -0400

Danny,

Thanks for answering my note, I'm not sure I'm going to address exactly
what you wrote below, but I wanted to give more of a background first of
how I'm approaching this.

I doubt that just "regular" java sockets are probably used much for large
scale web servers, but I think it will be useful to look at it in relation
to socket state for this discussion.

Using regular sockets you can read, write and close. on the Socket api are
methods isConnected and isClose, those seem to provide the state but don't.
isConnected says if the socket has been connected, not if it is currently
connected. isClose says if the socket has been closed by you, but not if
it has been closed by the other side (not sure we should give links in the
forum, so if you google something like "java why can't I tell if the socket
has been closed", you can see some explanations of this).

There is no way I know of using sockets, NIO, etc..... to know the state
of the connection without doing a Read and seeing if you get back some type
of close return code or exception. But then of course if no one is
waiting/listening for Read data, you are stuck with it. So the best thing
to do here is punt it up to the next layer, in this case the WebSocket API
user. That user has to handle a Close Error Conditon/Exception on an
outstanding Read or Write, or in the WebSocket case I guess that would be
using Endpoint.onError. Maybe not elegant, but no worse than regular
sockets and NIO!

I guess this also brings up another question, what is the scope/trigger for
Endpoint.onClose ? I can see this being triggered when a WebSocket close
frame has been received. I'm not sure outside of that what should trigger
it. If we read data at the socket layer and see we got an "end of stream"
before receiving the close frame, then I would think that would be an
error, so onError gets hit instead of onClose. If there is not a Read
outstanding then there is no decent way to determine if the other side has
in fact closed the connection.


To attempt to summarize:

getCloseStatus and isActive: I think are beyond the scope of the
information given to us by the underlying communication subsystem. Can the
user monitor if the close frame has been received using "onClose" and
therefore would not need these also?

getInactiveTime: I think is going to be very difficult to implement and
assumes read listeners are always outstanding. There is also an issue of
performance and timestamps. If you have 20000 active connections and you
need to keep track of the last time activity was done per each connection,
then you are calling some sort of time stamp method many many times, which
can get really expensive, and the information you are getting from those
timestamp calls are almost always going to be thrown away, overwritten or
not used. So I think from a performance standpoint WebSockets won't want
to do this.

onClose - We need to do as much as possible to define what drives this, and
also what is not expected to drive this. For example, the other side
closing the connection at the TCP layer (without sending a close frame) is
not expected to drive this.


regards,
Bill

Bill Wigger
wigger_at_us.ibm.com
Software Development
IBM Research Triangle Park




                                                                       
             Danny Coward
             <danny.coward_at_ora
             cle.com> To
                                       jsr356-experts_at_websocket-spec.java.
             08/09/2012 07:55 net
             PM cc
                                       Bill Wigger/Raleigh/IBM_at_IBMUS
                                                                   Subject
             Please respond to [jsr356-experts] Re:
             jsr356-experts_at_we Session.getCloseStatus isActive and
             bsocket-spec.java getInactiveTime
                   .net
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       




Hi Bill,

Thanks for the questions. I'm not sure if I'll answer them, but here's how
I was seeing it:-

It looks to me like the information we have about the session comes from
two places: one from the state of underlying TCP connection, and second
from the protocol itself. That information is incomplete, but I hope we can
provide something coherent to the user (not sure the API does it exactly
yet)

It looks like the session has 3 states that we could usefully model:-

1. 'ok' the underlying TCP connection has been established, it may or may
not be in the middle of transmitting/receiving data
2 a) 'broken': the underlying TCP connection has failed, network problem,
or it timed out.
2 b) 'formally closed': the peer in the interaction has formally closed the
session by sending a close frame.

Most of the time, my own guess is that developer will only care about
either 1) or 2) but not which flavor of 2 - a) or b).

The intention of isActive was to model 1 : isActive() true, and 2a)or2b) :
isActive() false.

And getCloseStatus() was returning the close frame sent by the peer if the
session is in state 2b). So getCloseStatus() being null could either be 2a)
or 1.

My thought was that states 1 vs 2a) are essentially derived from the health
of the underlying TCP connection (is that not cheap to determine?).

And a determination of being in state 1) is no guarantee the connection
will not fail the next moment, but I think its still useful information, as
is the inactive time determined by when the container marks the last
activity on the TCP connection. I think this kind of approach has been ok
for HttpSession's over the years.

Whether the connection was closed because someone cut the physical wire, or
whether the client send a close frame is I suspect of little interest to
most developers...so maybe there's a cleaner way to model these states in
the API while keeping the close frame info for those who want it ?

The protocol specific connection check is of course to do a Ping-Pong,
which is expensive. Maybe we should have some sort of checkActive() method
that does that in addition to the Ping/Pong APIs we have ?

- Danny


On 8/6/12 12:24 PM, Bill Wigger wrote:


      I have a question on the uses of the
      Session.getCloseStatus, .isActive, and .getInactiveTime

      getCloseStatus and isActive seem redundant in that if getCloseStatus
      returns null then it is Active. But beyond that I think that the
      information it supplies is not very useful and is supposing too much
      about the underlying communication protocol.

      From a useful standpoint, that status can change the moment after it
      is given, so just because the session returned as active, doesn't
      mean the calling code can assume it is active, since it could have
      been closed the moment after returning as active. And since the user
      can implement a close listener, then they already have a good way of
      knowing when it has been closed.

      Beyond usefulness though is the idea that the underlying protocol has
      a decent way of determining if a connection is closed or not. For
      some protocols on some operating systems one doesn't know, or at
      least cannot determine in an efficient manner, if the connection has
      been closed until a read or write fails, so if you don't have a read
      or write outstanding then there is no efficient way to determine if
      the connection has been closed. That's my biggest concern here,
      requiring the underlying subsystem to keep track of connection state
      and thereby producing a performance drag. And since the information
      can change momentarily, it doesn't seem like the upside of giving the
      (changeable) state back to the user is worth the downside of having
      to keep track of it.

      For getInactiveTime, I have basically the same concerns. That time
      can change momentarily, and if the intent here is to tell the user
      when, for example, read data has last come into the box, without the
      user having a read outstanding (in the form of a listener), then
      there isn't an efficient way to keep track of that information, and
      keeping track of it could be a drag on performance and scaling.

      Maybe I'm just misunderstanding what the information is that these
      APIs are suppose to relay, if so, please let me know.

      thank you,
      Bill





--
                   Danny Coward
                   Java EE
                   Oracle Corporation






graycol.gif
(image/gif attachment: graycol.gif)

pic27248.gif
(image/gif attachment: pic27248.gif)

ecblank.gif
(image/gif attachment: ecblank.gif)

2C862846.gif
(image/gif attachment: 2C862846.gif)