-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 27/02/2014 17:56, Christopher Schultz wrote:
> On 2/25/14, 3:31 AM, Mark Thomas wrote:
>> On 25/02/2014 06:03, Christopher Schultz wrote:

>>> It is important to make that distinction since the end user
>>> (the code) can't tell the difference?
>> 
>> The end user shouldn't be able to tell the difference. It is
>> important and it indicates that there is some overhead associated
>> with the process.
> 
> Aah, okay. A "true" blocking read or write would be more efficient,
> but you can't have both blocking and non-blocking operations on a
> connection after it's been established?

Java NIO provides no way of doing a true blocking read.

>>> Fourth, the "SSL Handshake" says non-blocking for NIO but
>>> blocking for the BIO and APR connectors. Does that mean that
>>> SSL handshaking with the NIO connector is done in such a way
>>> that it does not tie-up a thread from the pool for the entire
>>> SSL handshake and subsequent request? Meaning that the
>>> thread(s) that handle the SSL handshake may not be the same
>>> one(s) that begin processing the request itself?
>> 
>> Correct. Once request processing starts (i.e. after the request 
>> headers have been read) the same thread is used. Up to that
>> point, different threads may be used as the input is read (with
>> the NIO connector) using non-blocking IO.
> 
> Good. Are there multiple stages of SSL handshaking (I know there
> are at the TCP/IP and SSL level themselves -- I mean in the Java
> code to set it up) where multiple threads could participate --
> serially, of course -- in the handshake? I want to develop a
> pipeline diagram and want to make sure it's accurate. If the
> (current) reality is that a single thread does the SSL handshake
> and then another thread (possibly the same one) handles the actual
> request, then the diagram will be simpler.

There are multiple stages in the handshake but as far as Tomcat is
concerned is does these:

start handshake
while (need to read more data to complete handshake) {
  read data
  try and do more of the handshake
}

Each iteration of that loop may be handled by a different thread (with
the socket going back to the poller if there is no data available at
the moment). So it could be one thread, it could be as many threads as
there are bytes in the handshake.

> Let me take this opportunity to mention that while I could go read
> the code, I've never used Java's NIO package and would probably
> spend a lot of time figuring out basic things instead of answering
> the higher-level questions I'd like to handle, here. Not to mention
> that the connector-related code is more complicated than one would
> expect given the fairly small perceived set of requirements they
> have (i.e. take an incoming connection and allocate a thread, then
> dispatch). It's obviously far more complicated than that and there
> is a lot of code to handle some very esoteric requirements, etc.
> 
> I appreciate you taking the time to answer directly instead of 
> recommending that I read the code. You are saving me an enormous
> amount of time. ;)

I was tempted to say go and read the code but I know from experience
that is a time consuming task. The refactoring I did to reduce code
duplication was immensely instructive. I still get lost in that code
sometimes but it happens a lot less often.

>> The upgrade process is handled by the request processing thread
>> but once the upgrade is complete (i.e. the 101 response has been
>> returned) that thread returns to the pool.
> 
> Okay, so the upgrade occurs and the remainder of the request gets 
> re-queued. Or, rather, a thread is re-assigned when an IO event
> occurs.

Correct.

> Is there any priority assigned to events, or are they processed 
> essentially serially, in the order that they occurred -- that is, 
> dispatched to threads from the pool in the order that the IO events
> arrived?

It is the same poller as for the HTTP connections. Roughly they'll be
processed in arrival order but there may be a little re-ordering. It
depends on the behaviour of the selector.

>>> Also, (forgive my Websocket ignorance) once the connection has
>>> been upgraded for a single request, does it stay upgraded or is
>>> the next (keepalive) request expected to be a regular HTTP
>>> request that can also be upgraded?
>> 
>> The upgrade is permanent. When the WebSocket processing ends,
>> the socket is closed.
> 
> Okay, so if a client played its cards right, it could send a
> traditional HTTP request with keepalive, make several more requests
> over the same connection, and then finally upgrade to Websocket for
> the final request. After that, the connection is terminated
> entirely.

Yes.

> There is an implication there that if you want to use Websocket,
> don't use it for tiny request/response activities because
> performance will actually drop. One would be foolish to "replace"
> plain-old HTTP with Websocket but try to treat them the same.

Lots of tiny request responses over a long period of time would be
fine (and more efficient that HTTP). For a single request there is no
point switching to WebSocket.

The real benefit of WebSocket is that it is true two-way
communication. It is not limited to request, response, request,
response, etc.

>>> In the event that the request "stays upgraded", does the
>>> connection go back into the request queue to be handled by
>>> another thread, or does the current thread handle subsequent
>>> requests (e.g. BIO-style behavior, regardless of connector).
>> 
>> Either. It depends how the upgrade handler is written. WebSocket
>> uses Servlet 3.1 NIO so everything becomes non-blocking.
> 
> I think you answered this question above: the connection is closed 
> entirely, so there will never be another "next request" on that 
> connection, right?

For any upgraded connection that is correct. There is no way to
downgrade back to HTTP (at least not in the Servlet API anyway).

>>> I'm giving a talk at ApacheCon NA comparing the various
>>> connectors and I'd like to build a couple of diagrams showing
>>> how threads are allocated, cycled, etc. so the audience can get
>>> a better handle on where the various efficiencies are for each,
>>> as well as what each configuration setting can accomplish. I
>>> think I should be able to re-write a lot of the Users' Guide
>>> section on connectors (a currently mere 4 paragraphs) to help
>>> folks understand what the options are, why they are available,
>>> and why they might want to use one over the other.
>> 
>> I'd really encourage you to spend some time poking around in the 
>> low-level connector code debugging a few sample requests through
>> the process.
> 
> I will definitely do that, but I wanted to get a mental framework
> before I did. There's a lot of code in there... even the BIO
> connector isn't as fall-off-a-log simple as one might expect.

Some of that complexity is so we can share code between the
connectors. Some if it is there because we need to simulate
non-blocking (e.g. for WebSocket) and some of it is just old code that
needs cleaning up :)

I'll be sure to sit in on your talk. I'll try not to heckle too much
;) You can return the favour for my talks.

Mark


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTD5hfAAoJEBDAHFovYFnnrsEP/2J6V+YLKqq+ygSLbiHooEWS
qYiu8D1dG1Y2s0fpZjCK5gjrerAEoRZtGQgjbvR9ozb5Y0J+NU1H5OPePyR16HuG
Y0bgSMXQgTBbVgSe4xvZLACmsO6BH+XXY8xijnX/ayghd2js1BiOmdIhnnL9b+MY
uDfsc7mPy3cqj4bk98JqhtV3Z/SRuLh/F9xrcdkHPUhSjvw7Vb70tOKLjBbh9q1N
dK8y/9G1k31VbGV+JzHlWOFsj04yzXdcQVENmRLADvVt7CtFhupOByd+FApl8CjF
Mi+Hu4JUgG1S1QbEcLaLwdF4ACcGPPQ07bcc311eTl2cRHA/k0TeCLBrKAQsWcs/
qsiFT6gMq+Y9UY+4urvCYPZyfFzQbGGOR7hm2BGBXXUugNbvi6gyjLIhR4vQmpx2
wD11jh0DOOu6sCxbLn7TWLztzDd19VinJtT/lF/JXbNvZy/R8/MY60iST/pPpOgN
zXeHXMmH9+3sM+nPrNuSCoJhP1A7yxSFntlBaZpoRxbvKW40kFUEEaDwODRYOkcQ
lT9maq9GYfFUL4qau5DDEE9CUAT6E0Hb1bA2LYOPY7YmVLVHrzAcGo3j7evJ+XgE
6hAPBIBkZdCXvr4eWzlVXe223w0GdSdSKHjszzMxrOVNSaF+gZp83prnoIaI5KvI
X4tCzCsqMR6pC31seVWU
=bDkk
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to