users@grizzly.java.net

Re: Selector Thread Processing Insight

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Tue, 30 Mar 2010 11:36:21 +0200

Hi Ray,

> I'm trying to get an intuition on basic handling of an HTTP request
> and the various thread pools available to service requests. The
> below is a "guess" from an afternoon code crawl. Corrections _are_
> appreciated.
>
> 1. For a given port, say 8080, there is only ONE SelectorThread. It
> is literally a single thread. Only this thread is capable of
> processing an OP_ACCEPT on the port (listener socket). (????)
yes.

> 2. However a SelectorThread MAY be configured to use a pool of
> reader threads by setting the readerThreadCount to some positive
> number. This spreads the load for OP_READ reads across several
> threads. This is done inside the SelectorThread's Controller. In
> this case the Controller's SelectorHandler is an instance of
> RoundRobinSelectorHandler which handles the reads with a thread pool.
yes.


> 3. At some point when reading via the these polled reader threads,
> the request channel is handed off to a ProtocolFilter as a Task on
> its own WorkerThread, by default this is (wait for it) the
> DefaultProtocoalFilter! which is specifically a HTTP protocol filter/
> handler.
yes.

> 4. In turn the ProcessorTask MAY be configured to support async
> writing. If this is so, then a different selector (if available)
> will be used to perform the final output of the request.
It's opposite:) When you use sync. write - Grizzly will pickup
temporary selector, which will be used to write the entire data. If
use async write - Grizzly will try to write as much as possible data
in the current thread, but if internal socket buffer would be
overloaded - Grizzly won't block, but channel will be registered for
OP_WRITE on selector, mentioned in (2) and write the remainder once
selector will notify about channel availability.

>
> Endpoint [ACCEPT] (1 Selector/Thread) ->
> Readers [READ] (N ReadSelectors/Threads) ->
> ProtocolFilter [READ??, PROCESS_REQUEST_IN_ADAPTER](M WorkerTasks/
> Threads) ->
> OutputWriter [WRITE] (L WriteSelectors/Threads)

Just the last row should be fixed like:

(1) Endpoint [ACCEPT] (1 Selector/Thread) ->
(2) Readers [READ] (N ReadSelectors/Threads) ->
(3) ProtocolFilter [READ??, PROCESS_REQUEST_IN_ADAPTER](M WorkerTasks/
Threads) ->
(4) OutputWriter [WRITE] (Sync: WorkerThread of (3) | Async: M
WorkerThread).

> This gives up to 3 logic thread pools, one for a pool of reader
> threads, one for a pool of worker threads, and one for a pool of
> writer threads.
Just 2. There is no separate pool for a writer.


> Close so far???
Yep :)

> Do all of these share the ExecutorService threadPool in the
> SelectorThread. In other words if the SelectorThread.threadPool max
> threads is say 100. Then at most one can have 100 active readers,
> workers and writers?
Active - yes. Total - much much more.

Thanks.

WBR,
Alexey.


>
>
> Thanks,
>
> Ray
>
>
>
>
> --
> The object of life is not to be on the side of the majority, but to
> escape finding oneself in the ranks of the insane. - Marcus Aurelius