이희승 (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