I would add that just because you told the selectionKey to be ready for
a write by setting the OP_WRITE flag, and that the select() has been
interrupted because the underlying socket is ready to process a write
does not mean it's ready to be written when you try to do so : in the
mean time, the socket status might have changed.

I still don't see, from a technical point, how trying to write directly
into the socket could be problematic.

One possible case would be if the underlying OS were to accept anything
you try to write into the socket, even if the remote client does not
read anything, leading to data being stacked in memory. But I doubt any
decent system would ever do that...


Le 1/8/13 9:52 AM, Emmanuel Lécharny a écrit :
> Le 1/8/13 3:24 AM, Chad Beaulac a écrit :
>> On Jan 7, 2013, at 11:58 AM, Emmanuel Lécharny wrote:
>>
>>> Le 1/7/13 2:19 PM, Chad Beaulac a écrit :
>>>> If you don't push the data onto a queue and wait for the selector to fire, 
>>>> you could be trying to write data to a socket that is congestion 
>>>> controlled, which you shouldn't do. The writer should wait for the 
>>>> selector to fire saying the socket is writable before trying to write.
>>> The thing is that in any case, we do try to write into the socket. If
>>> the socket internal buffer gets full, we won't be able to write any ore
>>> data into it, and we will have to wait for the socket to inform the
>>> selector when it's ready to accept more data.
>>>
>>> What I'm proposing is not any different, except that I bypass the queue
>>> *if* and only *if* the socket is ready to accept new data. In other
>>> words, the algorithm is :
>>>  o if there is a queue containing messages waiting for the socket to be
>>> ready (OP_WRITE set ti true), then enqueue the new message.
>>>  o else try to write the message into the socket
>>>    - if we can't write the full message, set the SelectionKey to be
>>> interested in OP_WRITE, and enqueue the remaining data.
>>>    - Otherwise, the data have already been written anyway, we are done
>>>
>>> This is the way MINA 2 works since it's inception.
>>>
>>> Is there anything wrong with that ?
>>>
>> Potentially. You should not attempt to write to the socket unless the 
>> OP_WRITE selector key says the socket is writable. If the selector has fired 
>> and says the socket is writable before you try to write, it's not a problem. 
>> Otherwise, you should queue the data, let the Selector fire and then try to 
>> write. I don't see any way around queuing the data.
> Technically, in MINA 3, and in MINA 2, and in Netty, we actually *write*
> the data, then set the OP_WRITE if we weren't able to write the data
> into the socket, so when the socket is ready fro write, we can try
> again. In this case, the data are enqueued.
>
> But the fact is that it worked for years, without any problem.
>
>> You never want to try to write to a socket that is writable. If it isn't 
>> writable, it's closed or congestion controlled. This "edge-triggered" I/O 
>> approach works well. You don't know what "edge" you're on if you haven't 
>> registered for an event before you try to write.
> If the socket is not writable, then trying to write into it will just
> return 0. You immediately know that you should differ the write.
>
> Still trying to see where it can be a problem...
>


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com 

Reply via email to