AsynchronousSocketChannel.shutdownInput()
Alexander Libman
libman at terabit.com.au
Wed Aug 5 22:40:19 PDT 2009
Hi Gili, Alan
I have read again JavaDoc about encoder and looked at the source code of
ChasretEncoder. Basically, its state machine can be decribed as follows:
State Signal New State
--------- ------------------------- --------------
RESET encode(EOF=false) CODING
encode(EOF=true) END
reset RESET
flush Exception Illegal
CODING encode(EOF=false) CODING
encode(EOF=true) END
reset RESET
flush Exception Illegal
END encode(EOF=false) Exception Illegal
encode(EOF=true) END
reset RESET
flush FLUSHED
FLUSHED encode(EOF=false) Exception Illegal
encode(EOF=true) Exception Illegal
reset RESET
flush FLUSHED
This means we should have two kind of filters for AsynchronousCoders :
1) AsynchronousMessageEncoder:
2) AsynchonouseStreamEncoder
For the 1) AsynchronousMessageEncoder:
each asynchnous write (CharBuffer buffer) translates to the following
sequence of operations on encoder:
reset(); encode(EOF=true); flush();
shutdownOutput() simply prevents any future writes
close() calls shutdownOutput()
For the 2) AsynchronousStreamEncoder (Terabit version)
reset() called from constructor
each write() translates into encode(EOF=false)
shutdowOutput() translates into encode(zeroByteBuffer, EOF=true); flush();
and prevents any future writes
close() calls shutdownOutput()
The type of AsynchronousEncoder (Message or Stream) can be specified at
construction time.
Another possible option to introduce "HybridEncoder" with additional method
flush() that does not have analogy in AsynchronousByteChannel:
3) HybridEncoder works like:
reset() called from constructor
each write() translates into encode(EOF=false)
flush() translates into encode(zeroByteBuffer, EOF=true); flush(); reset()
shutdowOutput() translates into encode(zeroByteBuffer, EOF=true); flush();
and prevents any future writes
close() calls shutdownOutput()
another way to implement HybridEncoder (as Gili proposed):
reset() called from constructor
each write() translates into encode(EOF=false)
each write(EOF=true) translates into encode( EOF=true); flush(); reset()
shutdowOutput() translates into encode(zeroByteBuffer, EOF=true); flush();
and prevents any future writes
close() calls shutdownOutput()
Gili, you missed reset() in your implementation. write(EOF=true) does not
mean we can not write anymore,
it means end-of-transaction encoding and after flushing is done the encoder
is ready for next operations.
Any opinions? what interface is preferable?
I am thinking that Gili's write(buffer) and write(buffer,EOFFlag) make
sense.
One more option:
setMode(mode) method
messageMode -means write() works as 1) and
and
streamMode - means write() works as 2)
setMode () can be invoked at any time.
Alex
> -----Original Message-----
> From: nio-discuss-bounces at openjdk.java.net
> [mailto:nio-discuss-bounces at openjdk.java.net]On Behalf Of Gili
> Sent: Tuesday, August 04, 2009 11:27 PM
> To: nio-discuss at openjdk.java.net
> Subject: RE: AsynchronousSocketChannel.shutdownInput()
>
>
>
>
> Alexander Libman wrote:
> >
> > write() must return the number of elements (chars, not bytes!)
> processed
> > from the buffer(CharBuffer), i.e. consumed by encoder.
> > How many bytes encoder produces on output(i.e. on internal channel ) is
> > not
> > important for the caller.
> > "write () "is a job and "completed()" callback means the job is done.
> > If write() completed with less bytes processed than requested, it should
> > be
> > called again.
> > write() in TCP means data accepted for the trasnmission, but it does not
> > mean data is delivered.
> > It is up to decoder to buffer encoded data or to push them into internal
> > channel.
> > So shutdownOutput() works like flush and prohibits any future write
> > operations.
> > If error occurs during shutdownOutput() , exception should be thrown.
> > If you are still worried about all data are transmitted on internal
> > channel,
> > you can wait in external channel close() the completion of all
> operations
> > on internal channel.
> >
>
> Hi Alex,
>
> To be honest I don't fully understand the implications of
> CharsetEncoder.encode(endOfInput=true) and CharsetEncoder.flush(). If I
> write() 5 characters with endOfInput = false,
>
> 1) What's the point of CharsetEncoder.flush() if write(endOfInput=true)
> already knows that you're flushing? Is it because flush() is
> overridable by
> subclasses whereas encode() is not?
> 2) Am I guaranteed that the total characters outputted by
> CharsetEncoder.write() and flush() will be equal to 5 characters? I ask
> because the specification for flush() makes it seem as if there
> is no limit
> to the number of bytes it could output.
> 3) If I want to implement a method similar to
> OutputStream.flush() on top of
> CharsetEncoder, how would I do it? write(endOfInput=true) and
> flush() cannot
> be invoked more than once, whereas OutputStream.flush() can. But
> if I don't
> invoke them am I really flushing?
>
>
> Alexander Libman wrote:
> >
> > Yes, I know - it is still a draft, but it is working draft and I hope
> > the
> > code is not hard to read.
> > We will definetely try to find time to write better comments/doc.
> >
>
> Okay. I will try to finalize my implementation in the coming weeks. Once
> that's done we'll discuss folding it into nio2 or your framework. I'd like
> to hand maintenance over to someone else once I finish the stabilizing the
> code.
>
> Gili
> --
> View this message in context:
> http://n2.nabble.com/AsynchronousSocketChannel.shutdownInput%28%29
-tp3365782p3388926.html
Sent from the nio-discuss mailing list archive at Nabble.com.
No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.392 / Virus Database: 270.13.44/2282 - Release Date: 08/04/09
18:01:00
More information about the nio-discuss
mailing list