이희승 (Trustin Lee) wrote:
> No, you are not late. :)
> 
> 2008-03-04 (화), 13:27 -0700, Mike Heath 쓰시길:
>> First off, sorry for the LATE response tot his thread.  My comments are
>> below inline.
>>
>> 이희승 (Trustin Lee) wrote:
>>> Adding commit(Partial)?Response method causes HttpResponse to keep a
>>> response to IoSession, which doesn't sound good to me.  What do you
>>> think about providing another setContent method with Queue<IoBuffer>?
>>>
>>> We could provide a special implementation of Queue that allows a user to
>>> stream a list of IoBuffers on demand.  The encoder will try to access
>>> the queue by calling poll() to get the newest chunk.
>>>
>>> Actually this proposal causes some changes in ProtocolCodecDecoder and
>>> MINA itself so it can understand Queue<IoBuffer>.  However, the encoder
>>> won't need to be changed at all.
>>>
>>> Another trickier part is decoding.  I prefer to have HttpRequest (or
>>> HttpResponse) to have a Queue<IoBuffer> as a content so the decoder can
>>> offer the newly received chunk there.
>>>
>>> On the other hand, Use of the Queue interface might be inadequate and we
>>> might need to introduce more specialized interface like the following:
>>>
>>> public interface IoBufferStream {
>>>     void offer(IoBuffer buf);
>>>
>>>     // Returns null on the end of the content.
>>>     // Returns an empty buffer if no chunk is ready yet.
>>>     IoBuffer poll();
>>>
>>>     // and some listener registration...
>>>     IoBufferStream addListener(IoBufferStreamListener listener);
>>>     IoBufferStream removeListener(IoBufferStreamListener listener);
>>> }
>>>
>>> By having MINA core providing a standardized interface for streaming a
>>> large list of buffer chunks will make more broad range of users happier
>>> rather than implementing such a feature in a certain protocol provider.
>>>
>>> WDYT?
>> Don't we already have the equivalent of an IoBufferStream with just
>> IoSession.write() and IoHandler.messageReceived()?  It seams like this
>> would add a lot of complication just to solve the problem of partial
>> HTTP responses from AsyncWeb server.  Also, wouldn't use a Queue require
>> the decode to block waiting for messages to send?
> 
> Just to make sure if I got your point.. what equivalent do we have in
> MINA core?
> 
>> That being said, I don't like the HttpResponse object holding the
>> IoSession either.  You also have to think about the HTTP client.  On the
>> client side it doesn't make any sense to have an addContent on an HTTP
>> response.
>>
>> I'm more inclined toward something like:
>>
>> public interface PartialResponse {
>>
>>   void write(Object message);
>>
>>   void done();
>>
>>   addListener(PartialWriteListener listener);
>>
>>   removeListener(PartialWriteListener listener);
>>
>> }
>>
>> public interface PartialWriteListener {
>>
>>   void onWriteCompletion(PartialResponse partialResponse, Object
>> writtenMessage);
>>
>> }
>>
>> You would then do something like:
>>
>> PartialResponse partial = response.commitPartialResponse(httpResponse);
>> partial.write(startofData);
>> partial.addListener(new PartialWriteListener() {
>>   void onWriteCompletiion(PartialResponse partialResponse, Object
>> writtenMessage) {
>>     if (noMoreData) {
>>       partialResponse.done();
>>     } else {
>>       partialResponse.write(moreData);
>>     }
>>   }
>> });
>>
>> Thoughts?
>>
>> Of course, we still have to incorporate exception handling if an
>> exception is thrown from the listener as Tuure pointed out and this
>> doesn't address the notion of setting a chunk size as David pointed out.
> 
> I think we are on the same page actually.  If you look into the
> IoBufferStream, it's identical to PartialResponse:
> 
> * IoBufferStream.offer() = PartialResponse.write()
> * IoBufferStream.poll() = PartialResponse.done() and some internal
> method?
> * and listener methods.
> 
> What differences do you think of?  

In my example, calling PartialResponse.done() indicates that I'm done
sending a request.  This is telling AsyncWeb that it can now close the
IoSession or listen for another request.  In the case of chunked
encoding, it's also telling AsyncWeb to send the 'last-chunk' token.  If
chunked encoding is not being used, it tells AsyncWeb that it should
make sure I sent as much data as I said I would in 'Content-Length'.

IoBufferStream.poll() doesn't imply that to me but if that's what you
meant maybe we are talking about the same thing. :)

> However, my initial idea of integrating this interface tightly into the
> core is not good as you pointed out.  I'd rather want to provide this
> feature as a part of out-of-the-box filters.

I think a generic filter for doing this would be the best approach to
take and it would provide a valuable reusable component.

-Mike

Reply via email to