AsynchronousByteCharChannel and Timeouts

20 messages Options
Embed this post
Permalink
Gili

AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Hi,

Is it possible to move the timeout-related methods out of AsynchronousSocketChannel into their own  interface? I want AsynchronousByteCharChannel (character/line reader on top of an AsynchronousByteChannel) to be able to function on top of AsynchronousByteChannels that support timeouts. AsynchronousSocketChannel is one such channel, but so is SerialPortChannel which I've implemented on my end.

The methods in question are:

 void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);
 void write(ByteBuffer src, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);

Thanks,
Gili
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
I just defined such an interface. Let me know what you think:

AsynchronousByteChannelTimeouts.java

Gili

Gili wrote:
Hi,

Is it possible to move the timeout-related methods out of AsynchronousSocketChannel into their own  interface? I want AsynchronousByteCharChannel (character/line reader on top of an AsynchronousByteChannel) to be able to function on top of AsynchronousByteChannels that support timeouts. AsynchronousSocketChannel is one such channel, but so is SerialPortChannel which I've implemented on my end.

The methods in question are:

 void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);
 void write(ByteBuffer src, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);

Thanks,
Gili
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alternatively, we could define these methods in AsynchronousByteChannel and mark them as optional. Subclasses would then document whether they support timeouts or not. This would be a similar design to Collections.

I'm still trying to figure out how to design AsynchronousByteCharChannel for AsynchronousByteChannels with timeouts and without. If the timeout methods are optional then the design becomes quite simple. If not, I might have to create two different adapters: one for ByteChannels with timeouts, one for ones without it.

Ideas anyone?

Gili

Gili wrote:
I just defined such an interface. Let me know what you think:

AsynchronousByteChannelTimeouts.java

Gili

Gili wrote:
Hi,

Is it possible to move the timeout-related methods out of AsynchronousSocketChannel into their own  interface? I want AsynchronousByteCharChannel (character/line reader on top of an AsynchronousByteChannel) to be able to function on top of AsynchronousByteChannels that support timeouts. AsynchronousSocketChannel is one such channel, but so is SerialPortChannel which I've implemented on my end.

The methods in question are:

 void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);
 void write(ByteBuffer src, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);

Thanks,
Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Gili wrote:

> Alternatively, we could define these methods in AsynchronousByteChannel and
> mark them as optional. Subclasses would then document whether they support
> timeouts or not. This would be a similar design to Collections.
>
> I'm still trying to figure out how to design AsynchronousByteCharChannel for
> AsynchronousByteChannels with timeouts and without. If the timeout methods
> are optional then the design becomes quite simple. If not, I might have to
> create two different adapters: one for ByteChannels with timeouts, one for
> ones without it.
>
> Ideas anyone?
>
> Gili
>  
Another suggestion is to create a class that decorates a given
AsynchronousByteChannel, extending it with methods for timed operations.
You should be able to combine any AsynchronousByteChannel with the timer
support in j.u.c and create a nice solution.

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:
Another suggestion is to create a class that decorates a given
AsynchronousByteChannel, extending it with methods for timed operations.
You should be able to combine any AsynchronousByteChannel with the timer
support in j.u.c and create a nice solution.

-Alan.
I don't understand. Are you talking about adding functionality similar to Future.get(long timeout) on top of an existing byte channel? I was talking about the different between:

read(ByteBuffer dst, A attachment, CompletionHandler<Integer,? super A> handler);

and

 void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer, ? super A> handler);

As far as I know you can't implement the latter in terms of the former because you need to pass the timeout values to the underlying OS. What did you mean?

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Gili wrote:

> :
> I don't understand. Are you talking about adding functionality similar to
> Future.get(long timeout) on top of an existing byte channel? I was talking
> about the different between:
>
> read(ByteBuffer dst, A attachment, CompletionHandler<Integer,? super A>
> handler);
>
> and
>
>  void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment,
> CompletionHandler<Integer, ? super A> handler);
>
> As far as I know you can't implement the latter in terms of the former
> because you need to pass the timeout values to the underlying OS. What did
> you mean?
>  
You should be able to implement the timed variants using the non-timed
methods when combined with the timer support in java.util.concurrent.
That's what we do in the AsynchronousSocketChannel implementation and
should be applicable to other channel types too. All I was suggesting is
that this might be something useful to add to your library.

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:
You should be able to implement the timed variants using the non-timed
methods when combined with the timer support in java.util.concurrent.
That's what we do in the AsynchronousSocketChannel implementation and
should be applicable to other channel types too. All I was suggesting is
that this might be something useful to add to your library.
I wonder if this is a difference between socket communications and serial ports. As far as I know, there is no way for me to initiate a "wait forever" read against a serial port and then fire some method at a later time asking it to return as much data has it managed to gather so far.

Looking at http://msdn.microsoft.com/en-us/library/aa363437%28VS.85%29.aspx and http://msdn.microsoft.com/en-us/library/aa363791%28VS.85%29.aspx it seems that if you cancel a read (the only way I know of interrupting it) the operation will return zero bytes. Am I missing something?

Thanks,
Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Gili wrote:

> :
> I wonder if this is a difference between socket communications and serial
> ports. As far as I know, there is no way for me to initiate a "wait forever"
> read against a serial port and then fire some method at a later time asking
> it to return as much data has it managed to gather so far.
>
> Looking at http://msdn.microsoft.com/en-us/library/aa363437%28VS.85%29.aspx
> and http://msdn.microsoft.com/en-us/library/aa363791%28VS.85%29.aspx it
> seems that if you cancel a read (the only way I know of interrupting it) the
> operation will return zero bytes. Am I missing something?
>  
Cancellation of I/O operations is an awkward topic and clearly not
feasible on all operating systems and in all cases. The timeout support
in AsynchronousSocketChannel does not require it. This approach might be
worth exploring for your serial port channel but it really depends on it
if makes sense to want to continue to use the channel after a timeout.
In the case of AsynchronousSocketChannel, the timeout support is there
to make it easy to deal with cases where the peer does not respond. The
typical error handling includes close the channel. In the case of serial
I/O, how would you expect the application to handle a timeout?

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:
Gili wrote:
> :
> I wonder if this is a difference between socket communications and serial
> ports. As far as I know, there is no way for me to initiate a "wait forever"
> read against a serial port and then fire some method at a later time asking
> it to return as much data has it managed to gather so far.
>
> Looking at http://msdn.microsoft.com/en-us/library/aa363437%28VS.85%29.aspx
> and http://msdn.microsoft.com/en-us/library/aa363791%28VS.85%29.aspx it
> seems that if you cancel a read (the only way I know of interrupting it) the
> operation will return zero bytes. Am I missing something?
>  
Cancellation of I/O operations is an awkward topic and clearly not
feasible on all operating systems and in all cases. The timeout support
in AsynchronousSocketChannel does not require it. This approach might be
worth exploring for your serial port channel but it really depends on it
if makes sense to want to continue to use the channel after a timeout.
In the case of AsynchronousSocketChannel, the timeout support is there
to make it easy to deal with cases where the peer does not respond. The
typical error handling includes close the channel. In the case of serial
I/O, how would you expect the application to handle a timeout?
Here is a simple counter-example that comes to mind:

write() to request a computation on the remote end
read() with a timeout waiting for the result
if a timeout occurs, write() telling the queue to abort the computation

In the above case you could disconnect on timeout, reconnect and request an abort. Forcing a disconnect on a timeout is not the end of the world, but it seems like an unnecessary limitation. Instead of invalidating the channel, couldn't you have specified that in case of a timeout the API will return the number of bytes that were written by the underlying implementation (ideally zero) and leave it up to the user to decide if he wishes to disconnect or do something else?

In parallel, I will ask on another mailing list whether they have real-life use-cases of using a serial-port after a timeout.

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Gili wrote:

> :
> Here is a simple counter-example that comes to mind:
>
> write() to request a computation on the remote end
> read() with a timeout waiting for the result
> if a timeout occurs, write() telling the queue to abort the computation
>
> In the above case you could disconnect on timeout, reconnect and request an
> abort. Forcing a disconnect on a timeout is not the end of the world, but it
> seems like an unnecessary limitation. Instead of invalidating the channel,
> couldn't you have specified that in case of a timeout the API will return
> the number of bytes that were written by the underlying implementation
> (ideally zero) and leave it up to the user to decide if he wishes to
> disconnect or do something else?
>  
AsynchronousSocketChannel doesn't close the channel on timeout. Rather
it just invokes the completion handler's failed method with the
InterruptedByTimeoutException. In many cases the application will close
the channel at this point because the peer is not responding and there
is nothing it can do. The wording in the spec related to continued use
of the channel is to deal with possible implementations where it is
completely unfeasible to cancel an I/O operation and leave the
connection and channel is a consistent state. For example, suppose an
implementation is using blocking I/O then there may be thread blocked in
read or write and no way to unblock it cleanly. Another example may be
where it is possible to cancel an I/O but have no way to guarantee that
bytes haven't been transferred in/out of the socket buffer. That would
completely break stream communication and clearly this an area where
serial port I/O will differ (because you are at lower level and I assume
there is some protocol to over errors, right?. In other words, the
protocol will recover from data loss and other protocol errors).

-Alan.
Alexander Libman

RE: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
In addition to Alan comments.
we can consider timed operations as a contract to finish operation in
specified time interval.
Timeout error can be interpereted as kind of execution error and  it leaves
the channel in undefined state.
This is major difference between asynchronous and sychnoronous non-blocking
ways of programming.



For the algorithms  when  the content of the next portion data to send
depends depends not only on peer reply,
but also on the time of reply arrival or timeouts, we have to inroduce
imaginable "AsynchronousTimers"  with completion handlers.
Currently, we can use  Timer and TimerTask in java.util as
"AsynchronousTimer" and CompletionHandler.

Usually, the  Completion Handler invocation works as signal for protocol
state machine.
Now, we simply add  the number of signals to our state machine.
The main advantages are :
1) the single  TimerTask can be used as signal for several channels, i.e.
"watch dog" approach.
Would be nice, if the user can facility to register the watch dog time
interval and timer task for whole AsynchronousGroup.
This task can iterate over group channel and  for each channel invoke a
special callback.
Inside such callback the developer can  calculate the time expired from the
last started read/write operations.

2) very often we are not interested in time interval for particular I/O
operation, but rather we are inetresrted in transition from state A to state
B in specified time interval.
Between states A and B, it can be executed a lot of read/write operations.
AsynchronousTimer approach allows to resolve this task and keep the channel
in consistent state if we decide to change our actions in timed manner.

I am not sure do we want timed operations for artificial
AsynchronousChannels (Filters). Example, AsynchronousSSLChannel.
We have different timeout meaning for external and internal channels.
Support of general timeouts for the filters -I think it is too much
overhead.
Independent AsynchronousTimer makes life easy here as well.

For SerialPort  communications  AsynchrnousTimer aprproach works too.
You can setup: "A value of zero for both the ReadTotalTimeoutMultiplier and
ReadTotalTimeoutConstant members indicates that total time-outs are not used
for read operations."
Or it is possible to use both Windows  Comm timeouts to control the rate of
arriving bytes (like for low level data link protocol ) and  high
level-timeouts "Timers" for the application layer.

Alex








> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of Alan Bateman
> Sent: Monday, August 03, 2009 4:15 PM
> To: Gili
> Cc: [hidden email]
> Subject: Re: AsynchronousByteCharChannel and Timeouts
>
>
> Gili wrote:
> > :
> > Here is a simple counter-example that comes to mind:
> >
> > write() to request a computation on the remote end
> > read() with a timeout waiting for the result
> > if a timeout occurs, write() telling the queue to abort the computation
> >
> > In the above case you could disconnect on timeout, reconnect
> and request an
> > abort. Forcing a disconnect on a timeout is not the end of the
> world, but it
> > seems like an unnecessary limitation. Instead of invalidating
> the channel,
> > couldn't you have specified that in case of a timeout the API
> will return
> > the number of bytes that were written by the underlying implementation
> > (ideally zero) and leave it up to the user to decide if he wishes to
> > disconnect or do something else?
> >
> AsynchronousSocketChannel doesn't close the channel on timeout. Rather
> it just invokes the completion handler's failed method with the
> InterruptedByTimeoutException. In many cases the application will close
> the channel at this point because the peer is not responding and there
> is nothing it can do. The wording in the spec related to continued use
> of the channel is to deal with possible implementations where it is
> completely unfeasible to cancel an I/O operation and leave the
> connection and channel is a consistent state. For example, suppose an
> implementation is using blocking I/O then there may be thread blocked in
> read or write and no way to unblock it cleanly. Another example may be
> where it is possible to cancel an I/O but have no way to guarantee that
> bytes haven't been transferred in/out of the socket buffer. That would
> completely break stream communication and clearly this an area where
> serial port I/O will differ (because you are at lower level and I assume
> there is some protocol to over errors, right?. In other words, the
> protocol will recover from data loss and other protocol errors).
>
> -Alan.
> No virus found in this incoming message.
> Checked by AVG - www.avg.com
> Version: 8.5.392 / Virus Database: 270.13.43/2280 - Release Date:
> 08/03/09 17:56:00
>

Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alexander Libman wrote:
> In addition to Alan comments.
> we can consider timed operations as a contract to finish operation in
> specified time interval.
> Timeout error can be interpereted as kind of execution error and  it leaves
> the channel in undefined state.

        I don't think that it is safe to assume that timeouts are a form of
execution error. When I asked about timeouts on the RXTX mailing list a
lot of people responded that they expect to be able to use the channel
after a read() timeout. For example, some comport protocols "frame" data
packets using a timeout. So you read() and if a timeout occurs you
assume that the *next* read denotes a new packet or connection. In such
a case, you do not want to close and reopen the comport because you
might miss some bytes.

        I think it is perfectly reasonable for some channel implementations to
invalidate after a timeout, if this is the exception to the rule. What
worries me is that you seem to be implying the opposite: that
more-often-than-not a timeout error should result in the channel in an
undefined state.

        For some category of channels, such as comports, an implementation that
invalidates after a timeout is fairly useless.

> For the algorithms  when  the content of the next portion data to send
> depends depends not only on peer reply,
> but also on the time of reply arrival or timeouts, we have to inroduce
> imaginable "AsynchronousTimers"  with completion handlers.
> Currently, we can use  Timer and TimerTask in java.util as
> "AsynchronousTimer" and CompletionHandler.
>
> Usually, the  Completion Handler invocation works as signal for protocol
> state machine.
> Now, we simply add  the number of signals to our state machine.
> The main advantages are :
> 1) the single  TimerTask can be used as signal for several channels, i.e.
> "watch dog" approach.
> Would be nice, if the user can facility to register the watch dog time
> interval and timer task for whole AsynchronousGroup.
> This task can iterate over group channel and  for each channel invoke a
> special callback.
> Inside such callback the developer can  calculate the time expired from the
> last started read/write operations.

        I'm not sure I understand you correctly, but if I am then this isn't
ideal from a usability point of view. I want to read 1-n bytes within X
milliseconds or timeout with 0 bytes read. This sort of thing should be
implemented under the hood (since it's a common use-case) instead of
forcing me to implement it on top of the API in terms of timers.

> 2) very often we are not interested in time interval for particular I/O
> operation, but rather we are inetresrted in transition from state A to state
> B in specified time interval.
> Between states A and B, it can be executed a lot of read/write operations.
> AsynchronousTimer approach allows to resolve this task and keep the channel
> in consistent state if we decide to change our actions in timed manner.
>
> I am not sure do we want timed operations for artificial
> AsynchronousChannels (Filters). Example, AsynchronousSSLChannel.
> We have different timeout meaning for external and internal channels.
> Support of general timeouts for the filters -I think it is too much
> overhead.
> Independent AsynchronousTimer makes life easy here as well.
>
> For SerialPort  communications  AsynchrnousTimer aprproach works too.
> You can setup: "A value of zero for both the ReadTotalTimeoutMultiplier and
> ReadTotalTimeoutConstant members indicates that total time-outs are not used
> for read operations."
> Or it is possible to use both Windows  Comm timeouts to control the rate of
> arriving bytes (like for low level data link protocol ) and  high
> level-timeouts "Timers" for the application layer.

        I'm sorry. I couldn't understand what you're trying to say here :(

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
cowwoc wrote:

> :
>     I don't think that it is safe to assume that timeouts are a form
> of execution error. When I asked about timeouts on the RXTX mailing
> list a lot of people responded that they expect to be able to use the
> channel after a read() timeout. For example, some comport protocols
> "frame" data packets using a timeout. So you read() and if a timeout
> occurs you assume that the *next* read denotes a new packet or
> connection. In such a case, you do not want to close and reopen the
> comport because you might miss some bytes.
>
>     I think it is perfectly reasonable for some channel
> implementations to invalidate after a timeout, if this is the
> exception to the rule. What worries me is that you seem to be implying
> the opposite: that more-often-than-not a timeout error should result
> in the channel in an undefined state.
>
>     For some category of channels, such as comports, an implementation
> that invalidates after a timeout is fairly useless.
AsynchronousSocketChannel is intended to represent a connection to a
reliable stream. Applications using the channel are not expected to
tolerate data loss or data repetition in the stream. That paragraph on
timeouts is just saying that if, on timeout, that the implementation
cannot guarantee that bytes haven't been (or won't be) transferred then
it should prevent further I/O of that type on the channel. Also remember
the channel may have very different implementations, depending on the
operating system and I/O facility used. If implemented using blocking or
asynchronous I/O (for example) then it may be completely unfeasible to
cancel the I/O operation cleanly when the timer has expired. On the
other hand, there will be implementations (non-blocking based in
particular) where a timer can safely "cancel" with the guarantee that no
bytes have been transferred. In those cases, the channel can of course
be re-used. I can't say if this approach is completely suitable for your
serial port channel but it does seem like the timeout (or the Future
cancel if that style is used) will need to be able to cause the
underlying I/O to be cancelled.

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:
AsynchronousSocketChannel is intended to represent a connection to a
reliable stream. Applications using the channel are not expected to
tolerate data loss or data repetition in the stream. That paragraph on
timeouts is just saying that if, on timeout, that the implementation
cannot guarantee that bytes haven't been (or won't be) transferred then
it should prevent further I/O of that type on the channel. Also remember
the channel may have very different implementations, depending on the
operating system and I/O facility used. If implemented using blocking or
asynchronous I/O (for example) then it may be completely unfeasible to
cancel the I/O operation cleanly when the timer has expired. On the
other hand, there will be implementations (non-blocking based in
particular) where a timer can safely "cancel" with the guarantee that no
bytes have been transferred. In those cases, the channel can of course
be re-used. I can't say if this approach is completely suitable for your
serial port channel but it does seem like the timeout (or the Future
cancel if that style is used) will need to be able to cause the
underlying I/O to be cancelled.
Okay. I agree with everything you wrote except for the earlier post about how it should be possible to implement read-with-timeout in terms of read-forever. For the win32 comport API at least this doesn't seem to be possible. How does it work for sockets?

If you start a read for 10 bytes and a Timer tells you about a timeout after you only read 5 bytes are you saying you can tell the underlying OS to stop reading but also give you whatever data it already read? As I mentioned before, the OS lets me stop ongoing reads for serial ports but then it will queue any read data and I can only get at it if I try to read() again.

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Gili wrote:
> :
> Okay. I agree with everything you wrote except for the earlier post about
> how it should be possible to implement read-with-timeout in terms of
> read-forever.
Right, this is where we differ because AsynchronousSocketChannel does
not require the implementation to have a mechanism to cancel the
underlying I/O operation.

> For the win32 comport API at least this doesn't seem to be
> possible. How does it work for sockets?
>  
It's done using overlapped I/O with WSARecv/WSASend. A completion port
is used to receive the notifications when the I/O operations complete.
We don't make use of I/O cancellation (Windows Vista did bring a new
Win32 call to cancel specific I/O operations but it doesn't provide the
guarantees that we require and we don't use it).

If it were implemented as blocking sockets then the same issue would
arise (from the Win32 docs: "If a send or receive operation times out on
a socket, the socket state is indeterminate, and should not be used; TCP
sockets in this state have a potential for data loss, since the
operation could be canceled at the same moment the operation was to be
completed.")

> If you start a read for 10 bytes and a Timer tells you about a timeout after
> you only read 5 bytes are you saying you can tell the underlying OS to stop
> reading but also give you whatever data it already read? As I mentioned
> before, the OS lets me stop ongoing reads for serial ports but then it will
> queue any read data and I can only get at it if I try to read() again.
>  
A read operation is not required to fill the buffer so if you initiate a
read up to 10 bytes then it is normal have the read to complete having
read less than 10 bytes.

For the case that the timer expires at just around the time that 5 bytes
have been read into your buffer then the best solution is to have the
I/O operation complete (successfully) and the buffer position moved on
by 5 bytes. If you are saying that this is not feasible (because the
underlying read returns 0) then are those 5 bytes lost? If this were a
stream/socket then this data loss would be a disaster if the application
were to read bytes after the timeout and data loss. For a serial
connection (we are talking RS232 or descendants, right?) then it's not
too bad as there will likely be a high level protocol to detect errors.

-Alan.





Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:

> It's done using overlapped I/O with WSARecv/WSASend. A completion port
> is used to receive the notifications when the I/O operations complete.
> We don't make use of I/O cancellation (Windows Vista did bring a new
> Win32 call to cancel specific I/O operations but it doesn't provide the
> guarantees that we require and we don't use it).
>
> If it were implemented as blocking sockets then the same issue would
> arise (from the Win32 docs: "If a send or receive operation times out on
> a socket, the socket state is indeterminate, and should not be used; TCP
> sockets in this state have a potential for data loss, since the
> operation could be canceled at the same moment the operation was to be
> completed.")

        Weird. Comports (and sockets too I believe!) can be treated as HANDLEs
in the win32 API. You can then use ReadFile(), CancelIo() to read and
cancel overlapped operations. CancelIo() has the limitation of only
being cancellable from the thread that initiated the read but you can
use "completion ports" to work around this limitation and essentially
get the Windows Vista functionality back in Windows XP. That's what I'm
using for comports. Couldn't you do the same for sockets?

> For the case that the timer expires at just around the time that 5 bytes
> have been read into your buffer then the best solution is to have the
> I/O operation complete (successfully) and the buffer position moved on
> by 5 bytes. If you are saying that this is not feasible (because the
> underlying read returns 0) then are those 5 bytes lost?

        To be honest, it's not clear. CancelIo() claims to cancel any pending
I/O operations. My interpretation is that if I issue an overlapped read
for 10 bytes but CancelIo() after 5 the read bytes would get buffered
for future reads (i.e. I don't lose any data). I posted this question to
double check:
http://stackoverflow.com/questions/1238905/does-cancelio-cause-data-loss

> If this were a stream/socket then this data loss would be a disaster if the application
> were to read bytes after the timeout and data loss. For a serial
> connection (we are talking RS232 or descendants, right?) then it's not
> too bad as there will likely be a high level protocol to detect errors.

        While this is true on a higher level, I can't assume that all serial
protocols will have error detection/correction and users would probably
refuse to use a library that silently eats bytes ;) At the very least I
would need to make such failures more explicit.

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
cowwoc wrote:
> :
>     Weird. Comports (and sockets too I believe!) can be treated as
> HANDLEs in the win32 API. You can then use ReadFile(), CancelIo() to
> read and cancel overlapped operations. CancelIo() has the limitation
> of only being cancellable from the thread that initiated the read but
> you can use "completion ports" to work around this limitation and
> essentially get the Windows Vista functionality back in Windows XP.
> That's what I'm using for comports. Couldn't you do the same for sockets?
No, because it cancels all pending I/O operations on the handle
(initiated by the calling thread) and so can't be used when there may be
more than one I/O operation outstanding that was initiated from the same
thread (meaning read and write). Furthermore, the initiating thread may
be executing a completion handler and so may not return to poll the
completion port in a timely manner. The CancelIoEx call introduced in
Vista does address these limitations but we don't have any plans to use
it. The only Vista specific feature we are using here is the new thread
agnostic I/O so that I/O operations can be initiated on non-pooled threads.

> :
>     While this is true on a higher level, I can't assume that all
> serial protocols will have error detection/correction and users would
> probably refuse to use a library that silently eats bytes ;) At the
> very least I would need to make such failures more explicit.
I'm not suggesting you silently eat bytes, but rather look for a
solution that would allow the operation to complete successfully for the
case that bytes are transferred into the buffer at just around the time
that the timer expires. That would be more desirable than data loss. If
you do have data loss, and you do allow the application to read again
from the channel then you are dependent on the high-level protocol to
recover. Clearly data loss with a stream connection is more fatal.

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
Alan Bateman wrote:

> cowwoc wrote:
>> :
>>     Weird. Comports (and sockets too I believe!) can be treated as
>> HANDLEs in the win32 API. You can then use ReadFile(), CancelIo() to
>> read and cancel overlapped operations. CancelIo() has the limitation
>> of only being cancellable from the thread that initiated the read but
>> you can use "completion ports" to work around this limitation and
>> essentially get the Windows Vista functionality back in Windows XP.
>> That's what I'm using for comports. Couldn't you do the same for sockets?
> No, because it cancels all pending I/O operations on the handle
> (initiated by the calling thread) and so can't be used when there may be
> more than one I/O operation outstanding that was initiated from the same
> thread (meaning read and write).  Furthermore, the initiating thread may
> be executing a completion handler and so may not return to poll the
> completion port in a timely manner. The CancelIoEx call introduced in
> Vista does address these limitations but we don't have any plans to use
> it. The only Vista specific feature we are using here is the new thread
> agnostic I/O so that I/O operations can be initiated on non-pooled threads.

        Oops! It seems we've just discovered a bug in my code :) Fixing this is
not going to be fun :( I think what I'll have to do is reserve two
threads per channel (one for read, one for write) and use a thread pool
for handling completion handlers.

> I'm not suggesting you silently eat bytes, but rather look for a
> solution that would allow the operation to complete successfully for the
> case that bytes are transferred into the buffer at just around the time
> that the timer expires. That would be more desirable than data loss.

        Any idea on how to do this?

Gili
Alan Bateman

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
cowwoc wrote:
> :
>     Any idea on how to do this?
How about  using WaitForMultipleEvents to multiplex the handle to the
serial port and a handle to an event that is set when the timer expires.
That should work for the Future usage too as you can set the event when
the cancel method is invoked. It would tie up one of the threads in your
thread pool for the duration of the I/O operation, but I assume that
this wouldn't be a problem as the number of serial ports it likely to be
small (I would guess).

-Alan.
Gili

Re: AsynchronousByteCharChannel and Timeouts

Reply Threaded More More options
Print post
Permalink
In reply to this post by Alan Bateman
Hi Alan,

Replies below...

Alan Bateman wrote:
Gili wrote:
> :
> Okay. I agree with everything you wrote except for the earlier post about
> how it should be possible to implement read-with-timeout in terms of
> read-forever.
Right, this is where we differ because AsynchronousSocketChannel does
not require the implementation to have a mechanism to cancel the
underlying I/O operation.
I've got an idea I want to run by you. I propose defining read/write with timeout at the AsynchronousByteChannel level because it'll simplify the class hierarchy (no need to define separate helper classes for read-with-timeout versus read-without-timeout). I believe that these methods can be implemented across all platforms in the following way:

Case 1: read(forever), followed by Future.cancel()
\-> if the native layer supports read(timeout) then we emulate read(forever) in terms of a loop containing read(timeout) where timeout is a reasonably small value. The loop runs until data becomes available or until Future.cancel() is invoked. In the latter case, Future.cancel() blocks until the timeout completes and then return true. Any data read before Future.cancel() is invoked is buffered for subsequent reads.
\-> if the native layer does not support read(timeout), Future.cancel() returns false and subsequent reads throw RuntimeException (similar to AsynchronousSocketChannel).

Case 2: read(forever) with a CompletionHandler: the native read terminates when data becomes available or if the channel is closed.

Case 3: read(timeout) with a CompletionHandler
\-> if the native layer supports timeouts, the native read terminates when data becomes available, a timeout occurs or the channel is closed.
\-> if the native layer does not support timeouts and a timeout occurs before the native read completes then subsequent reads throw RuntimeException.

Case 4: write(forever), followed by Future.cancel()
\-> if the native layer supports write(timeout) then we emulate write(forever) in terms of a loop containing write(timeout) where timeout is a reasonably small value. The loop runs until data becomes available or until Future.cancel() is invoked. In the latter case, Future.cancel() blocks until the timeout completes and then return true. If Future.cancel() is invoked before a single byte is written then no data is written, otherwise any data not yet sent is buffered to proceed subsequent writes.
\-> if the native layer does not support write(timeout), Future.cancel() returns false and subsequent reads throw RuntimeException.

Case 5: write(timeout) with a CompletionHandler: the native write terminates when the data is fully written or if the channel is closed.

Case 6: write(timeout) with a CompletionHandler
\-> if the native layer supports timeouts, the native write terminates when the data is fully written, a timeout occurs or the channel is closed.
\-> if the native layer does not support timeouts and a timeout occurs before the native write completes then subsequent reads throw RuntimeException.

Let me know what you think.

Thanks,
Gili