<div>Hi Frederic,</div>
<div> </div>
<div>You got it all correct in my application. Thanks so much for the help.</div>
<div>Following your suggestion, I was able to maximize the concurrency by adding a ChannelFutureListener on connect operation. In its operationComplete(), channel sent a http request and count down a CountDownLatch since I do need to &#39;join&#39; all responses.</div>

<div> </div>
<div>So now, I have used 3 loops (vs previously 4 loops), plus more concurrency, like this:</div>
<div> </div>
<div>- Setup the first CountDownLatch</div>
<div>- Loop 1: connect n times with a listener for each connect. In the listener&#39;s operationComplete(), request was sent, handler list was added </div>
<div>              and a CountDownLatch was counted down.</div>
<div>- wait on the first CountDownLatch</div>
<div>- Loop 2: use the handler list to retrieve each response.</div>
<div>
<div>- Setup the second CountDownLatch</div>
<div>- Loop 3: do a channel.getCloseFuture().addListener. In the listener&#39;s operationComplete(), simply count down the CountDownLatch</div>
<div>
<div>- wait on the first CountDownLatch</div>
<div>- bootstrap.releaseExternalResources</div>
<div> </div>
<div>I think I&#39;m now observing now better performance than before AFTER a threshold. In my case, in serving less than 100 requests, multi-threading plus synch Apache HttpClient does better. In serving 100 requests, they break even. In serving 200 and 300 requests, Netty does better. My VMware workstation 6 with Centos 5.3 and 5gb mem in a 4-cores desktop cannot handle more than 300 requests in my simple testing application.</div>

<div> </div>
<div>Next, I&#39;m going to work on HttpChunkAggregator as you suggested. Not sure what else I need to do other than uncommenting out that line in snoop example. I&#39;ll look into it.</div>
<div> </div>
<div>Again, thanks so much to guide me as a newbie to this framework.</div>
<div> </div>
<div>Jason</div></div>
<div> </div></div>
<div class="gmail_quote">On Fri, Sep 11, 2009 at 12:30 AM, Frederic Bregier <span dir="ltr">&lt;<a href="mailto:fredbregier@free.fr">fredbregier@free.fr</a>&gt;</span> wrote:<br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote"><br>Hi Jason,<br><br>Again, I&#39;m feeling not able to answer to all, but I will start to answer to<br>some...<br>
<br>One of the interest of the Nio model is the asynchronous part.<br>In your example, if I get it correctly you do something like this:<br>For all host/port<br>   connect<br>For all connect<br>   wait their finished connection and send request<br>
For all connected<br>   wait for the answer for one request in order<br><br>Then you are implementing something in the middle of synchronous and<br>asynchronous.<br>I would have the following idea (using all ChannelFuture capability of<br>
Netty):<br><br>For all host/port<br>   connect and add a ChannelFutureListener on the connection done<br><br>In the ChannelFutureListener<br>   send the request =&gt; each request will add (not necesseraly in order) the<br>
result in your arraylist<br><br>Wait for the list to be full (n requests =&gt; n answers or using a countdown<br>from concurrent package)<br><br>Then you can have connection/sending request/receiving request all<br>overlapping between several requests.<br>
<br>What you have done tend to be synchronous, not completely since you overlap<br>connections between all channel connection, but as you are waiting that all<br>are done...<br>You can get it by this &quot;picture&quot;:<br>
you create n task (connection)<br>you are waiting that all n task are done (connected) so a global<br>synchronisation of all threads<br>then you create n task (request)<br>you are waiting that all n task are done (answered) so again a global<br>
synchronisation<br><br>What I suggest is:<br>you create n task (connection), they will continue by sending the request<br>(no synchronisation)<br>you are waiting that all n task (connected and answered) are done (on any<br>
order) so a global synchronisation but based on the slowest answer from<br>remote host.<br><br>Of course, if you can avoid to wait for all answers to be there and work<br>with each answer one by one, then you can even avoid such a global wait on<br>
the slowest answer. But it depends on you business logic there...<br><br>Reusing connection is not quite possible in Netty but there is some<br>handlers/code that allow reconnection (Trustin made an example a few days<br>
ago posted in the ML).<br><br>Now for the chunk part, yes chunk should be supported by any HTTP server.<br>The reason is that when a request is bigger than 8KB, it is supposed to be<br>chunked.<br>However, there is in Netty an handler (HttpChunkAggregator) that allow you<br>
to get the full body (only the body is concerned by chunk) in one<br>ChannelBuffer. This handler does accumulating of all chunks up to the last<br>one and returns to the next handler when it is completed.<br>It is obviously simplest for a standard program.<br>
However take care of one thing, it means that if you have 100 requests and<br>if all requests sends 1MB of body, then you will have 100 MB in memory (at<br>least) since it will store all bodies in memory until they finished to<br>
decode all chunks.<br>In my work, I use the Http codec chunk by chunk since I am able with my<br>business model to handle data chunk by chunk so keeping the memory as low as<br>possible.<br>But if it is not your case, just use the HttpChunkAggregator handler, it<br>
works perfectly and then you can ignore if the answer is chunked or not. In<br>the snoop example there is an example on how to use it.<br><br>HTH,<br>Frederic<br>
<div>
<div></div>
<div class="h5"><br><br>J. Mi wrote:<br>&gt;<br>&gt; Thanks to Frederic for the overview. It&#39;s very helpful for me.<br>&gt;<br>&gt; I have come up with an approach to replace my multi-thread model with<br>&gt; Netty&#39;s HttpClient. It&#39;s pretty much based on the snoop example. I<br>
&gt; just added 3 loops to achieve the concurrency (multiple http requests at<br>&gt; the<br>&gt; same time). The first loop was around the call to bootstrap.connect(new<br>&gt; InetSocketAddress(host, port)). The second loop was waiting for each<br>
&gt; connection attempt to succeed and then send the request. The third loop<br>&gt; was<br>&gt; using the handler to retrieve each http response by using a<br>&gt; LinkedBlockingQueue. I used ArrayList to maintain a list for<br>
&gt; ChannelFuture,<br>&gt; a list for Channel and a list for HttpResponseHandler among these 3 loops.<br>&gt;<br>&gt; Everything worked well for me with the approach. However, my test result<br>&gt; didn&#39;t seem to show this approach out-perform my multi-thread model, i.e.<br>
&gt; one thread (java.util.concurrent) for each http request which was done by<br>&gt; Apache Commons HttpClient (a synchronous model). My performance was<br>&gt; measured<br>&gt; by timing the total time spent in making n http requests and retrieving<br>
&gt; this<br>&gt; n http responses end-to-end.<br>&gt;<br>&gt; With requests below 50, the multi-thread model performed a little better.<br>&gt; I<br>&gt; was hoping Netty&#39;s way can catch up for better scaling because I was<br>
&gt; concerned about the current muti-thread model may not scale well when<br>&gt; getting hundreds requests at the same time. But I still failed to observe<br>&gt; any increased performance relative to the multi-thread model beyond<br>
&gt; serving<br>&gt; 50, 100, 200...800 concurrent requests.<br>&gt;<br>&gt; One thing I need to understand more (Frederic already touched some basics<br>&gt; here) is about the connection management. I felt that Apache Commons<br>
&gt; HttpClient seemed to manage the connection with possible reuse. Not<br>&gt; exactly<br>&gt; sure about how Netty does that.<br>&gt;<br>&gt; One more question about Netty&#39;s HttpClient. In its<br>&gt; HttpResponseHandler.java,<br>
&gt; messageReceived() method only receives a portion of response at a time and<br>&gt; has a dependence on server&#39;s responding with &quot;chunked&#39; Transfer-Encoding<br>&gt; header and content for an end of response condition. This raised 2<br>
&gt; questions: (1) is there a way to receive response in one shot, like<br>&gt; Apache&#39;s<br>&gt; HttpClient; and (2) do all Http server required to respond with &quot;chunked&quot;<br>&gt; content? In my case, I need to retrieve online responses from different<br>
&gt; web<br>&gt; sites.<br>&gt;<br>&gt; Cheers,<br>&gt; Jason<br>&gt;<br>&gt;<br>&gt;<br>&gt; On Thu, Sep 10, 2009 at 6:45 AM, Frederic Bregier<br>&gt; &lt;<a href="mailto:fredbregier@free.fr">fredbregier@free.fr</a>&gt;wrote:<br>
&gt;<br>&gt;&gt;<br>&gt;&gt; Hi,<br>&gt;&gt;<br>&gt;&gt; I will not talk about the specific Http part of Netty but about its main<br>&gt;&gt; interest, the NIO of Netty.<br>&gt;&gt; Of course, Trustin or others can be more precised than me. It is just my<br>
&gt;&gt; general comprehension (I&#39;m not a Nio expert neither a Netty expert, so it<br>&gt;&gt; is<br>&gt;&gt; just my comprehension as an end user).<br>&gt;&gt;<br>&gt;&gt; To compare to a standard Blocking IO, Netty uses less threads to manage<br>
&gt;&gt; the<br>&gt;&gt; same behaviour.<br>&gt;&gt; For instance, if you think about Apache or Tomcat, one connection will be<br>&gt;&gt; handled by at least one thread through the full life of the connection.<br>&gt;&gt; So<br>
&gt;&gt; if you have 1000 connections, you will have at least 1000 threads.<br>&gt;&gt; In Netty, a thread will be active when data arrives into the server (the<br>&gt;&gt; general idea is greatly simplified here, it is not to take it as the<br>
&gt;&gt; reality). For instance, for those 1000 connections, maybe at most 100 are<br>&gt;&gt; really sending something on the same time to the server, so around 100<br>&gt;&gt; threads will be used. Netty does something like reusing threads, whatever<br>
&gt;&gt; the connection is.<br>&gt;&gt;<br>&gt;&gt; Another point of course is the non blocking way. Once you send something,<br>&gt;&gt; you have the choice to continue the job without waiting that the data is<br>&gt;&gt; really sent (of course, you have to take care about it for instance<br>
&gt;&gt; before<br>&gt;&gt; closing the channel). So you can overlap sending data with other<br>&gt;&gt; computations (for instance for next packet to be sent).<br>&gt;&gt; Compares to blocking IO, of course, there you wait for the data to be<br>
&gt;&gt; really<br>&gt;&gt; sent (or at least buffered).<br>&gt;&gt;<br>&gt;&gt; So in many points, Netty approach should have more performance than<br>&gt;&gt; blocking<br>&gt;&gt; IO. I said &quot;should&quot; since there exist some counter examples where<br>
&gt;&gt; blocking<br>&gt;&gt; IO are faster, since NIO introduces some extra computing comparing to<br>&gt;&gt; blocking IO. However most of the time, these extra are masked by the<br>&gt;&gt; implementation of Netty and are quicker than blocking IO. But I recall<br>
&gt;&gt; some<br>&gt;&gt; examples however.<br>&gt;&gt;<br>&gt;&gt; Also, Netty can have different kind of transport (nio, oio, ...), so the<br>&gt;&gt; behaviour can be different according to one or another low network<br>
&gt;&gt; transport<br>&gt;&gt; framework.<br>&gt;&gt;<br>&gt;&gt; This is not the full idea of Netty, but a start of answer to your<br>&gt;&gt; question.<br>&gt;&gt; For more information, either other people can continue this thread (or<br>
&gt;&gt; correct where I a wrong), and of course you can read the examples that<br>&gt;&gt; are<br>&gt;&gt; in Netty (even those not about Http) and the documentation of Netty.<br>&gt;&gt;<br>&gt;&gt; HTH,<br>&gt;&gt; Cheers,<br>
&gt;&gt; Frederic<br>&gt;&gt;<br>&gt;&gt; J. Mi wrote:<br>&gt;&gt; &gt;<br>&gt;&gt; &gt; Hi all,<br>&gt;&gt; &gt;<br>&gt;&gt; &gt; I guess my fundamental question here is if, in theory at least, Netty<br>&gt;&gt; &gt; provides a better asynchronous mechanism than the concurrent java<br>
&gt;&gt; package<br>&gt;&gt; &gt; from java.util.concurrent.* in terms of performance. Does internally<br>&gt;&gt; Netty<br>&gt;&gt; &gt; use multi-threading, java.nio, or both, or neither?<br>&gt;&gt; &gt;<br>&gt;&gt; &gt; If Netty does better than java.util.concurrent.* for performance, is<br>
&gt;&gt; there<br>&gt;&gt; &gt; any example, tutorial, which can guide me a little for replacing my<br>&gt;&gt; &gt; current<br>&gt;&gt; &gt; multi-threading process which I described in that previous email?<br>&gt;&gt; &gt;<br>
&gt;&gt; &gt; Many thanks to you for sharing your expertise,<br>&gt;&gt; &gt; Jason<br>&gt;&gt; &gt;<br>&gt;&gt; &gt; On Wed, Sep 2, 2009 at 12:11 PM, J. Mi &lt;<a href="mailto:jmi258@gmail.com">jmi258@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt;<br>&gt;&gt; &gt;&gt; Hi folks,<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt; Currently, my application&#39;s process flow logic is like this:<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt; -&gt; A controlling process receives one request for data which will be<br>
&gt;&gt; &gt;&gt; fetched from multiple online sources.<br>&gt;&gt; &gt;&gt; -&gt; The controlling process spawns multiple threads. Each of these<br>&gt;&gt; threads<br>&gt;&gt; &gt;&gt; will (1) use Apache synchronous commons httpclient to fetch the data;<br>
&gt;&gt; (2)<br>&gt;&gt; &gt;&gt; parse the data; and (3)<br>&gt;&gt; &gt;&gt;     return the data to the controlling process.<br>&gt;&gt; &gt;&gt; -&gt; The controlling process joins all threads and return the combined<br>
&gt;&gt; data<br>&gt;&gt; &gt;&gt; to the requestor.<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt; So basically, each thread uses a synchronous httpclient to fetch the<br>&gt;&gt; data<br>&gt;&gt; &gt;&gt; and then parse it.<br>
&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt;  In reading org.jboss.netty.example.http.snoop package, I have the<br>&gt;&gt; &gt;&gt; following question:<br>&gt;&gt; &gt;&gt; If I just replace the Apache&#39;s synchronous httpclient with Nettty&#39;s<br>
&gt;&gt; &gt;&gt; org.jboss.netty.handler.codec.http.* as the example does, will I be<br>&gt;&gt; &gt;&gt; benefited performance-wise? I heard something about blocking I/O hurts<br>&gt;&gt; &gt;&gt; multi-threading. If so, should Netty&#39;s package work better for me?<br>
&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt; Or should I actually get ride of the existing multi-threading by using<br>&gt;&gt; &gt;&gt; Netty&#39;s framework? If so, which of your examples can be better<br>&gt;&gt; referenced<br>
&gt;&gt; &gt;&gt; for my purpose?<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt; Thanks for your in advance,<br>&gt;&gt; &gt;&gt; Jason<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;&gt;<br>&gt;&gt; &gt;<br>&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; netty-dev mailing list<br>&gt;&gt; &gt; <a href="mailto:netty-dev@lists.jboss.org">netty-dev@lists.jboss.org</a><br>&gt;&gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/netty-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-dev</a><br>
&gt;&gt; &gt;<br>&gt;&gt; &gt;<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; -----<br>&gt;&gt; Hardware/Software Architect<br>&gt;&gt; --<br>&gt;&gt; View this message in context:<br>&gt;&gt; <a href="http://n2.nabble.com/A-question-about-your-HttpClient-example-and-beyond-tp3568879p3617420.html" target="_blank">http://n2.nabble.com/A-question-about-your-HttpClient-example-and-beyond-tp3568879p3617420.html</a><br>
&gt;&gt; Sent from the Netty Developer Group mailing list archive at Nabble.com.<br>&gt;&gt; _______________________________________________<br>&gt;&gt; netty-dev mailing list<br>&gt;&gt; <a href="mailto:netty-dev@lists.jboss.org">netty-dev@lists.jboss.org</a><br>
&gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/netty-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-dev</a><br>&gt;&gt;<br>&gt;<br>&gt; _______________________________________________<br>&gt; netty-dev mailing list<br>
&gt; <a href="mailto:netty-dev@lists.jboss.org">netty-dev@lists.jboss.org</a><br>&gt; <a href="https://lists.jboss.org/mailman/listinfo/netty-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-dev</a><br>
&gt;<br>&gt;<br><br><br>-----<br>Hardware/Software Architect<br>--<br></div></div>View this message in context: <a href="http://n2.nabble.com/A-question-about-your-HttpClient-example-and-beyond-tp3568879p3624150.html" target="_blank">http://n2.nabble.com/A-question-about-your-HttpClient-example-and-beyond-tp3568879p3624150.html</a><br>

<div>
<div></div>
<div class="h5">Sent from the Netty Developer Group mailing list archive at Nabble.com.<br>_______________________________________________<br>netty-dev mailing list<br><a href="mailto:netty-dev@lists.jboss.org">netty-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/netty-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-dev</a><br></div></div></blockquote></div><br>