3

I'm programming a simple Java NIO server and have a little headache: I get normal InputStreams i need to pipe to my clients. I have a single thread performing all writes, so this creates a problem: if the InputStream blocks, all other connection writing will be paused.

I can use InputStream.available() to check if there are any incoming data I can read without blocking, but if I've reached end-of-stream it seems I must call read() to know.

This creates a major headache for me, but I can't possibly believe I'm the first to have this problem.

The only options I've come up with so far:

  • Have a separate thread for each InputStream, however that's just silly since I'm using non-blocking I/O in the first place. I could also have a thread pool doing this but then again that limits the amount of simultaneous clients I can pipe the InputStream to.
  • Have a separate thread reading these streams with a timeout (using another thread to interrupt if reading has lasted longer than a certain amount of time), but that'll most certainly choke the data flow should I have many open InputStreams not delivering data.

Of course, if there was a magic InputStream.isEof() or isClosed() then this wouldn't be any problem at all :'(

Arne
  • 3,006
  • 1
  • 22
  • 21
  • 1
    Using blocking IO is not silly at all. You can get as good or better performance with it. Do you know this is actually a problem? – Peter Lawrey Apr 05 '11 at 08:02
  • Yes, the server needs to support a large number of persistent connections (20,000+). – Arne Apr 05 '11 at 08:48
  • You cannot use InputStream in a non-blocking way and there is no getting around this. I suggest you replace the system which is giving you an InputStream or use multiple threads as you have done. How many of these thread could there be? If its less than 1K I wouldn't worry about it. – Peter Lawrey Apr 05 '11 at 08:50
  • If you have over 10K connections, have you considered using more than one server? – Peter Lawrey Apr 05 '11 at 08:51
  • Using more than one server is of course possible, but it would require a lot more coding for my part since some of the connections inter-communicate through the server. Sure, nothing's impossible, but I'd rather not rewrite the whole thing :) -- and I'm on a limited budget. – Arne Apr 05 '11 at 09:55

2 Answers2

3

".....Have a separate thread for each InputStream, however that's just silly since I'm using non-blocking I/O in the first place...."

It's not silly at all. First you need to check whether you can retrieve a SelectableChannel from your InputStream implementation. If it does you are lucky and you can just register it with a selector and do as usual. But chances are that your InputStream may have a channel that's not a SelectableChannel, in which case "Have a separate thread for each InputStream" is the obvious thing to do and probably the right thing to do.

Note that there is a similar problem discussed in SO about not able to get a SelectableChannel from an inputstream. Unfortunately you are stuck.

Community
  • 1
  • 1
Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
  • Thanks, I think I got what I need now! – Arne Apr 07 '11 at 09:51
  • 'whether you can retrieve a SelectableChannel from your InputStream implementation' -- you can only get a channel from a socket if the socket originated with SocketChannel.open() or ServerSocketChannel.accept(). It's in the Javadoc. Luck has nothing to do with it. – user207421 Apr 15 '11 at 06:33
-1

I have a single thread performing all writes

Have you stopped to consider whether that is part of the problem rather than part of the solution?

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    I can't have one thread per connection as I need to support a large amount of concurrent connections. – Arne Apr 05 '11 at 09:43
  • @Arne: *non sequitur.* You would be surprised how many threads a modern JVM supports given the right hardware and OS. – user207421 Apr 05 '11 at 10:50
  • Yes, I've seen the discussion going on. I don't know enough to have an opinion, I just need to have it working right out of the box without tweaking the OS or anything, and using low amounts of RAM. Then again, you could just as well point out that such servers should be made in Erlang and that I'm a moron for using Java.. the list goes on :) – Arne Apr 05 '11 at 11:59
  • @Peter Absolutely, that would be wise, and I probably will, but the problem stays the same :( – Arne Apr 05 '11 at 12:02