0

my application has a queue with " outgoing network packets" (A POJO with a ByteBuffer and a SocketChannel) inside, consumed by a single thread that writes the data to the SocketChannel.

I do this to guarantee that every client that should receive packets, gets its turn. This means that SocketChannel.write() writes sequentially to multiple clients (= 1 at a time).

Can anyone tell me what could go wrong working like this? The SocketChannels are created from a ServerSocketChannel, so they're blocking.

I fear that the write() operation could block for 1 client, making the other clients wait...

Jonas
  • 121,568
  • 97
  • 310
  • 388
AndrewBourgeois
  • 2,634
  • 7
  • 41
  • 58
  • Is there a reason why you are not using Netty? – tolitius Nov 10 '11 at 07:16
  • Why would a client care if some other client has received his packet before or after another one? How could he even know it? He probably cares about getting it fast, and multithreading would allow this. – JB Nizet Nov 10 '11 at 07:35
  • @JBNizet: I just thought it would make sense to guarantee that 1 client doesn't have to wait "forever" to get his packet when the server load is 100%, and the JVM decides to ignore that thread. I think that the JVM is allowed to do that. – AndrewBourgeois Nov 10 '11 at 09:27
  • @tolitius: No reason at all, I'm just experimenting. If you can tell me where to look inside Netty I'll do that. – AndrewBourgeois Nov 10 '11 at 09:27
  • 1
    If the OS did ignore threads (that's where the scheduler is: in the OS), it could as well ignore your main thread and you would have all your clients waiting forever. Truts the scheduler. It works well. – JB Nizet Nov 10 '11 at 09:44

2 Answers2

2

The write() operation can indeed block in blocking mode. If you want fairness and single threading you will have to use non-blocking mode.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • But if I want the complete packet written before processing the next one, I still have the problem. Or what do you propose? I only THINK that having a queue and 1 consumer thread is good for fairness, I'm not saying it really is, I'm open for suggestions, It's for a test project I do for fun... – AndrewBourgeois Nov 10 '11 at 08:41
  • I think fairness is not what's important here. Suppose you go to a supermarket and there are 3 clients each with a different cashier. You are arriving and pay at a fourth cashier. Do the three other clients care if you leave the supermarket before them? Your implementation of fairness consists in having a single cashier for all the clients: this is where the supermarket will have angry clients. – JB Nizet Nov 10 '11 at 09:18
  • @AndrewBourgeois I don't understand what your comment has to do with my answer. (a) *Why* do you want the complete packet written before processing the next one? the client can't tell, and (b) there's nothing 'fair' about blocking the entire server while you service one client. – user207421 Nov 10 '11 at 09:33
  • @EJP: (a) Right, I could just put the buffer with remaining data at the end of the queue. (b) So you agree with JB Nizet, I should trash the idea and just write in the thread of the client, as the queue idea is worse? – AndrewBourgeois Nov 10 '11 at 10:06
0

If a client socket fails to consume all the data in one write (non-blocking), you could close the client. This will only happen when the buffer fills, so you could increase the send buffer of the socket to a level where you are comfortable doing this.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130