On Sun, 2008-06-22 at 17:10 +0200, Quintin Beukes wrote: > Hey, > > I understand and agree to everything you said. > > I made a small program (based on one of the NIO examples) to test NIO, > by minimally emulating what our program does (thread wise). Then I > made a thread pool executor to get it to run with a similar state, > executing requests at similar intervals that we usually expect to > receive at medium "busy-ness". > > I then monitored netstat and noticed a new connection being opened for > each and every request. Also, the EventListener's connectionOpen() is > called after each request, which makes it obvious that connection's > aren't being reused. > > I debugged the ConnectionReuseStrategy, and it does, however, return > true, which also becomes obvious with connections timing out > eventually (they weren't closed after HC was done with them). > > I have not myself worked with NIO at API level, but I did attempt to > see where connection reuse is done in NIO, though I failed to find it. > I'm sure with more effort I can find it, but first I'd try and see if > there is something obvious I'm missing. > > I put a cleaned up version online. This is cleanest I think I can go > to demonstrate what I'm talking about: > http://quintin.dev.junkmail.co.za/NHttpTest.java > > It's very close to the basic NIO client example. > > Even if I can just get the following, it should be sufficient for now: > 1. Connection re-use > 2. Total maximum > 3. Per host maximum (like host1:8580 = 5, host2:8580 = 10) > 4. Blocking when maximum is reached, until one becomes available >
Quintin, (1) There is nothing wrong with the connection reuse code. The problem is that the demo application opens a new connection for _each_ request rather than reusing the existing ones. The connections simply keep on piling up. (2) Be careful with blocking behaviors. If your code gets blocked while executing on the I/O dispatch thread, this will effectively block _all_ connections. No I/O events could be dispatched anymore. (3) HttpCore does not provide a sophisticated connection management mechanism similar to that in the HttpClient package. This is something that we still plan to build at some point. Currently one need to write a lot of management code to control the behavior of the connecting I/O reactor. Again, if you are under the time pressure, you might be better off improving your code based on the blocking I/O rather than trying to wrap your head around the complexity of NIO. Oleg > Q > > On 6/22/08, Oleg Kalnichevski <[EMAIL PROTECTED]> wrote: > > Quintin Beukes wrote: > > > > > > > > > What are the functional requirements you are trying to fulfill? What is > > > > it exactly you are trying to achieve? > > > > > > > > > > > > > I need to detect when a connection is open or not. > > > > > > But let me draw a picture of my problem. I have a max of 20 connections. > > > After a period of high concurrency all these connections were opened and > > > added to the pool. Then a period of quiet follows and all these sockets > > > time > > > out. Now the pool has 20 references to closed connections. > > > > > > So I try one. The pool thinks it's still open and returns it. A > > > NoResponse > > > exception is thrown. I remove it and try another one, same story. > > > > > > I remove it, but this time I try with an isStale() check. The isStale() > > > check doesn't really help in this case, but I would like to be able to > > > have > > > some check that can see if the connection is open. I figured I could > > > write > > > my own isStale() check that sends a request to the server, but if NIO is > > > possible, it would be much nicer to have a reliable isOpen() check done > > > first, to avoid the overhead of making an actual request to the server. > > > > > > The side effect of the above problem is that the next 20 connections > > > fail, > > > since it first tries to use all those in the pool. > > > > > > An alternative is to force open a new connection on the 3rd try, but I > > > would > > > also like to be able to check if a connection is really open. > > > > > > > > > > You should not keep connections in the pool infinitely and should have an > > eviction policy of some kind. For instance, close all connections that have > > been idle for more than 30 sec. You could even have different eviction > > settings per host, as you might want to evict connections to less reliable > > hosts more aggressively > > > > > > > > > > > > > > Why would you need anything else? A connection is either re-usable or > > > > not? > > > > > > > > > > > > > We used to use a commercial load balancer, and am implementing some of > > > it's > > > features into our custom one. > > > > > > These are ones like reusing connections to benefit from the server's > > > cache. > > > Like if a certain server just served http://somehost/logo.png, then have > > > that same server serve it again. > > > > > > This one can be implemented in the TargetHost selection, but not ones > > > like > > > configurable per host maximums. Like Host X can only have 10 open > > > connections, where the stronger host Y can have 20 open connections. Or > > > if > > > host Z doesn't have available connections, host Y can stand in and take > > > over the request if certain conditions are met, and this has to update > > > the > > > Heap structure for the load balancer. An example of such a condition is > > > for > > > example, is this a request for a list of known static files of less than > > > 100kbss. If these conditions aren't met, then the connection fetching > > > should > > > block until one becomes available. > > > > > > > > > > Right, but this still does not invalidate ConnectionReuseStrategy because > > it purpose is to test whether a connection is re-usable from the HTTP > > protocol standpoint. If you can still implement a more sophisticated > > connection re-use policy but there is no point trying to re-use connections > > that are deemed non re-usable by the protocol. > > > > Hope this helps > > > > > > Oleg > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
