Client usage IOStrategy's with TCPNIOTransport

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Client usage IOStrategy's with TCPNIOTransport

Daniel Feist
Hi,

I believe I fully understanding the use of IOStrategies when using
Grizzly as a Http Server, and am currently using the
WorkerThreadIOStrategy given that handling of http requests will not
be non-blocking in my scenario.  It is also clear that with this
strategy a worker thread will be used to handle READ and CLOSE
IOEvents, but not ACCEPT events.  This all makes sense.

That said, I'm slightly confused about the role of IOStrategies in
Client scenarios, particularly with the WorkerThreadIOStrategy:

- From examples I see that client implementations typically call
ctx.write to send the http request within an CompletionHandler after
asycronously establishing a connection.
- With this approach the kernal thread pool is used for the async
connection, but is also then used to perform the ctx.write including
HttpFilter processing etc.  (this is because WorkerThreadIOStrategy
only provides threadpool for READ/CLOSE events).
- When the response is recieved from the remote server, this is a READ
event, and so the WorkerThreadIOStrategy provides workers such that
each response is handed off to a worker thread before HttpFilter is
processed.

What seems strange about this when using:

i) Why does sending of request occurs in selector thread and not a
worker thread when WorkerThreadIOStrategy is being used?

ii) There appears to be a mismatch between use of worker thread for
response processing but not request processing and I'm unsure why if
there is only a limited number of selectors sending requests (say 4),
I'd want a thread pool of (say up to 200) workers to handle responses.

Make sense?  Is anyone able to shed any light on this?

thanks again,

Dan
Reply | Threaded
Open this post in threaded view
|

Re: Client usage IOStrategy's with TCPNIOTransport

oleksiys
Administrator

On 09.12.14 13:45, Daniel Feist wrote:

> Hi,
>
> I believe I fully understanding the use of IOStrategies when using
> Grizzly as a Http Server, and am currently using the
> WorkerThreadIOStrategy given that handling of http requests will not
> be non-blocking in my scenario.  It is also clear that with this
> strategy a worker thread will be used to handle READ and CLOSE
> IOEvents, but not ACCEPT events.  This all makes sense.
>
> That said, I'm slightly confused about the role of IOStrategies in
> Client scenarios, particularly with the WorkerThreadIOStrategy:
>
> - From examples I see that client implementations typically call
> ctx.write to send the http request within an CompletionHandler after
> asycronously establishing a connection.
> - With this approach the kernal thread pool is used for the async
> connection, but is also then used to perform the ctx.write including
> HttpFilter processing etc.  (this is because WorkerThreadIOStrategy
> only provides threadpool for READ/CLOSE events).
> - When the response is recieved from the remote server, this is a READ
> event, and so the WorkerThreadIOStrategy provides workers such that
> each response is handed off to a worker thread before HttpFilter is
> processed.
>
> What seems strange about this when using:
>
> i) Why does sending of request occurs in selector thread and not a
> worker thread when WorkerThreadIOStrategy is being used?
It is initiated by user, so Grizzly just sends the message in whatever
thread picked by user.

> ii) There appears to be a mismatch between use of worker thread for
> response processing but not request processing and I'm unsure why if
> there is only a limited number of selectors sending requests (say 4),
> I'd want a thread pool of (say up to 200) workers to handle responses.
In general, if we know the code is not blocking - we suggest to not do
or do as less as possible thread-context switches.
The asymmetry may be explained by the fact, that writing we perform is
non-blocking, but response processing might be blocking and we don't
want to block Selector thread.

Thanks.

WBR,
Alexey.
Reply | Threaded
Open this post in threaded view
|

Re: Client usage IOStrategy's with TCPNIOTransport

Daniel Feist
>> i) Why does sending of request occurs in selector thread and not a
>> worker thread when WorkerThreadIOStrategy is being used?
>
> It is initiated by user, so Grizzly just sends the message in whatever
> thread picked by user.

Yes, although when async connection and a completion handler is used,
this will actually use a grizzly selector thread rather than the
application thread.  This makes sense though, and is after-all an
implementation choice.

>> ii) There appears to be a mismatch between use of worker thread for
>> response processing but not request processing and I'm unsure why if
>> there is only a limited number of selectors sending requests (say 4),
>> I'd want a thread pool of (say up to 200) workers to handle responses.
>
> In general, if we know the code is not blocking - we suggest to not do or do
> as less as possible thread-context switches.
> The asymmetry may be explained by the fact, that writing we perform is
> non-blocking, but response processing might be blocking and we don't want to
> block Selector thread.

Makes sense.  In my scenario, which for now is blocking
request-response, I'll be using SameThreadIOStrategy given that
responses once parsed are simply set on a waiting future in
application thread.

What got me thinking about use of worker threads for request
processing and if the IOStrategy should be defining this was the
following code in AHC;

https://github.com/AsyncHttpClient/async-http-client/blob/master/providers/grizzly/src/main/java/org/asynchttpclient/providers/grizzly/FeedableBodyGenerator.java#L182

Here, regardless of the IOStrategy in use the worker threadpool is
accessed directly and used. This of course breaks when
SameThreadIOStrategy is used, and a ThreadPoolConfig needs to be set
manually.

thanks!


>
> Thanks.
>
> WBR,
> Alexey.