AsynchrronousByteChannel vs AsynchronousFileChannel and AsynchronousTransmitter
Alexander Libman
libman at terabit.com.au
Sun Apr 26 19:52:19 PDT 2009
Hi Alan, hi all
Thinking about AsynchronousTransmitter with draft prototype:
AsynchronousTransmitter {
private AsynchrnousTransmitter (....);
public static <A>
Future<AsynchronousTransmitter>
transmit(AsynchronousChannel inChannel,
AsynchronousChannel outChannel,
A attachment,
CompletionHandler<AsynchronousTransmitter, ? super A> handler)
/* The AsynchrnousTransmitter instance is accessible via returned Future<>
*/
public long getTotalBytesRead ();
public long getTotalBytesWritten ();
}
where inChannel and outChannel can be any combination of
AsynchrnousByteChannel/AsynchronousFileChannel(s).
Seems it would be helpful, if the AsynchronousFileChannel was derived from
AsynchrnonousByteChannel. Otherwise, we have to provide four similar
prototypes and implementations for Transmitter.
We can find other examples when we want to process file sequentially as
AsynchronousByteChannel and
asynchronously at same time.
Thr point why AsynchronousFileChannel is not derived from
AsynchronousByteChannel:
a) AsynchronousFileChannel operations require additional parameter
"position",
while AsynchrnousByteChannel does not. To inroduce additional and not used
argument "position"
for AsynchrnousByteChannel is acceptable for C-style API, but not acceptable
for OO languages like Java, C++.
b) AsynchronousFileChannel can have multiple outstanding read/write
opearations since parameter
"position" defines location to read/write and the sequence of operations is
not important.
While AsynchrnonousByteChannel usually supports only one pending read and
one pending write due "out-of-order" execution/completion problem.
What do you think about following solution: to add to the
AsynchronousFileChannel two properties:
"defaultReadPosition" and "defaultWritePosition".
They can be easily implemented as AtomicLong's.
Default positions do not impact at all on existing read/write operations
with position argument.
But they give us a chance to work AsynchronoudFileChannel as with
AsynchronousByteChannel.
Only one pending read is allowed for defaultReadPosition, i.e. read
operation in AsynchronousByteChannel style(no argument "position").
The defaultReadPosition is atomically adjusted just before setting completed
state, so next asynchronous read will pick up the adjusted position.
The same is true for write operations with defaultWritePosition.
As an example, we developed a draft of "AsynchronousByteFileChannel" which
works like a filter and implements AsynchrnousByteChannel inteface.
The only one difference with the filter is : the "inner" channel is
AsynchnornousFileChannel instead of AsynchronousByteChannel.
The source can be found:
http://jproactor.svn.sourceforge.net/viewvc/jproactor/trunk/nio2/src/au/com/
terabit/nio2/filter/AsynchronousByteFileChannel.java
BTW, during prototyping of AsynchronousByteFileChannel, we found that
simple filters can be easily developed
using only AsynchronousFuture and no AsynchronousFilter is required.
http://jproactor.svn.sourceforge.net/viewvc/jproactor/trunk/nio2/src/au/com/
terabit/nio2/filter/AsynchronousFuture.java
With term "simple" filter it is assumed filter with mapping 1:1 for "outer"
and "inner" operations. Such filter
acts as small interceptor on operation starts and completions.
For complicated filters (stateful engines like SSL), the base class
AsynchrnousFilter is still preferred solution.
And finanally coming back to the beginning - AsynchronousTransmitter.
Having AsynchronousByteFileChannel AsynchtronousTransmitter becomes a very
small class, which
can transmit both files and sockets:
http://jproactor.svn.sourceforge.net/viewvc/jproactor/trunk/nio2/src/au/com/
terabit/nio2/filter/AsynchronousTransmitter.java
and small test example
http://jproactor.svn.sourceforge.net/viewvc/jproactor/trunk/nio2/src/au/com/
terabit/nio2/testfilter/TestTransmitter.java?view=log
Definetely, real AsynchrnousTransmitter should use
TransmitFile()/TransmitPackets() API for Windows and
sendfile() for POSIX whenever it is possible. But in cases when API does not
exist or does not support pair source/destination,
the current solution can be used.
Alex
More information about the nio-dev
mailing list