On Sat, 2005-08-20 at 09:09 -0500, Sam Berlin wrote: > It is possible to use timeouts when using NIO, however you have to add > the behaviour in (and the timing will never be exact). Essentially, > you just need to maintain a secondary object per selection-attachment > that keeps track of the timeout required for that operation, and do > short timed-out selects.
Sam, The trouble is that as soon as the channel is put into a non-blocking mode and selectors get involved, the raw I/O throughput takes a significant hit (10-20% on reads, 50-100% on writes). Using selectors only to calculate timeouts on what is essentially a blocking connection simply does not make sense in terms of performance no matter whether one selector per multiple channels or one selector per channel are being used. Non-blocking NIO starts paying off only when costs of switching between several thousand mostly idle connection threads starts exceeding the performance penalty caused by the use of selectors Basically I lean toward concluding that NIO proved inferior to old I/O in all but a few special cases. Only when the number of concurrent connections does exceed a thousand, I would consider using NIO. This the reason why the Tomcat team has repeatedly rejected proposals to port Tomcat HTTP connector to NIO. A pool of worker threads acting on a queue of relatively short lived connections will always outperform one thread / many channels model as long as the number of concurrent connections does not reach a thousand. For what it is worth. Cheers, Oleg > If the current time after the select > finishes exceeds the time allotted for an event, that SelectionKey is > cancelled and the associated channels are closed. This is much easier > to do with connects, because it's a one-time behaviour -- but it is > possible to do with reads (and with writes it's also possible, even > though there never was a parameter for timing out on writes with > blocking streams). > > Thanks, > Sam > > On 8/20/05, Oleg Kalnichevski <[EMAIL PROTECTED]> wrote: > > On Fri, 2005-08-19 at 22:10 -0400, Michael Becke wrote: > > > Is using selectors the only way to support read timeout? > > > > The only one I know of and I have been working with NIO for quite some > > time > > > > > We certainly > > > could choose which factory to use based up SO_TIMEOUT, but it seems > > > like a bit of a hack. There must be a better way. Would it be > > > possible to use blocking NIO and the old method for handling > > > SO_TIMEOUT and still see some of the performance benefits of NIO? > > > > > > > Not that I know of. This is what the javadocs say: > > "...Enable/disable SO_TIMEOUT with the specified timeout, in > > milliseconds. With this option set to a non-zero timeout, a read() call > > on the InputStream associated with this Socket will block for only this > > amount of time..." > > > > SO_TIMEOUT will have effect on > > channel.socket().getInputStream().read(stuff); > > > > SO_TIMEOUT will have NO effect on > > channel.read(stuff); > > > > There are enough people who have been complaining loudly about it, > > because this pretty much renders blocking NIO useless. > > > > Oleg > > > > > Mike > > > > > > On 8/19/05, Oleg Kalnichevski <[EMAIL PROTECTED]> wrote: > > > > Folks, > > > > > > > > I think we (and especially I) have been looking at the problem from a > > > > wrong angle. Fundamentally the blocking NIO _IS_ faster than old IO (see > > > > the numbers below). This is especially the case for small requests / > > > > responses where the message content is only a coupe of times larger than > > > > the message head. NIO _DOES_ help significantly speed up parsing HTTP > > > > message headers > > > > > > > > tests.performance.PerformanceTest 8080 200 OldIO > > > > ================================================ > > > > Request: GET /tomcat-docs/changelog.html HTTP/1.1 > > > > Average (nanosec): 10,109,390 > > > > Request: GET /servlets-examples/servlet/RequestInfoExample HTTP/1.1 > > > > Average (nanosec): 4,262,260 > > > > Request: POST /servlets-examples/servlet/RequestInfoExample HTTP/1.1 > > > > Average (nanosec): 7,813,805 > > > > > > > > tests.performance.PerformanceTest 8080 200 NIO > > > > ================================================ > > > > Request: GET /tomcat-docs/changelog.html HTTP/1.1 > > > > Average (nanosec): 8,681,050 > > > > Request: GET /servlets-examples/servlet/RequestInfoExample HTTP/1.1 > > > > Average (nanosec): 1,993,590 > > > > Request: POST /servlets-examples/servlet/RequestInfoExample HTTP/1.1 > > > > Average (nanosec): 6,062,200 > > > > > > > > The performance of the NIO starts degrading dramatically only when > > > > socket channels is unblocked and is registered with a selector. The sole > > > > reason we need to use selectors is to implement read socket timeout. To > > > > make matters worse we are forced to use one selector per channel only to > > > > simulate blocking I/O. This is extremely wasteful. NIO is not meant to > > > > be used this way. > > > > > > > > Fundamentally the whole issue is about troubles timing out idle NIO > > > > connections, not about NIO performance. What if we just decided to NOT > > > > support socket timeouts on NIO connections? Consider this. On the client > > > > side we could easily work the problem around by choosing the type of the > > > > connection depending upon the value of the SO_TIMEOUT parameter. > > > > Besides, there are enough client side applications where socket read > > > > timeout is less important total the request time, which require a > > > > monitor thread anyway. This kind of applications could benefit greatly > > > > from NIO connections without losing a bit of functionality. The server > > > > side is by far more problematic because on the server side socket read > > > > timeout is a convenient way to manage idle connections. However, an > > > > extra thread to monitor and drop idle connections may well be worth the > > > > extra performance of NIO. > > > > > > > > What do you think? > > > > > > > > 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] > > > > > > > > > > > > --------------------------------------------------------------------- > > 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] > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
