Re: Time outs and state machines
- From: "Leslie Sanford" <jabberdabber@xxxxxxxxxxxxxxxxx>
- Date: Mon, 27 Feb 2006 22:56:13 -0600
"Robert Oliver" wrote:
Leslie Sanford wrote:
I have a state machine that sends messages to an external device.
After sending each message, the state machine waits for 20
milliseconds. If it has not received an acknowledgment (ACK) from the
receiving device when the 20 milliseconds have elapsed, it assumes a
non-handshaking mode and sends the next message. On the other hand,
if it does receive an acknowledgment before the 20 milliseconds have
elapsed, it sends the next message immediately.
What is it you are trying to achieve with this protocol? For example,
you may know it will take somewhat less than 20 ms to handle a single
message, but that some messages can be handled much faster. This
approach could increase throughput. Or, you could be worried that
missing an ACK would shutdown the entire channel and by waiting 20 ms
to send the next message, you might be able to keep going. Or, it
could be something else.
The protocol is the MIDI Sample Dump Standard. According to the
protocol, after sending each data packet, you wait for an ACK message.
If one hasn't arrived in 20 milliseconds, you assume a non-handshaking
mode for the next message and send it. This process is repeated for each
message, i.e. you switch back to handshaking mode and wait for an ACK or
another 20ms to have elapsed.
What do you expect is the likelihood that an ACK will be missed? Is
is an expected occurrence or does it represent an error?
I'm not sure about how likely it is for an ACK to be missed. I think the
protocol is designed in such a way so that it will work regardless of
whether or not the receiving device implements handshaking.
As far as it being an error, that's how I would choose to treat it. Once
handshaking is established, treating a missing ACK as an error would
seem valid. Perhaps it is, and I've misunderstood the protocol.
The way I have implemented this is to have a timer that sends a
one-shot timer event when the specified interval has elapsed, in this
case 20 milliseconds. If the state machine receives an
acknowledgement from the receiving device before the timer event has
elapsed, it stops the timer, sends the message, and starts the timer
again to begin the whole process all over again, i.e. send message
wait for ACK, etc...
There is a scenario that's probably rare but it's bothering me.
Suppose the receiving device sends an ACK message just before the
timer elapsed event. The ACK message gets put on the queue and
immediately after the timer event places its message on the queue as
well. The state machine consumes the ACK message. The next message in
the queue is the timer event. When the state machine consumes it, it
believes that the 20 milliseconds for the last message have elapsed
when in fact they have not.
What happens then? Is a message lost? What happens if it is?
Missing an ACK is often a good indication that a message was missed,
yet you don't sound worried about that. Should you worry about
sending two closely spaced messages?
Well, what I'm worried about here is the timer elapsed event being
misinterpreted by my state machine. The rule basically is that a data
packet is sent in response to either an ACK or the 20ms timer elapsed
event, whichever comes first. If it is an ACK, the timer is stopped so
that in theory it doesn't have a chance to place an elapsed event on the
message queue. But as I look at this, I can imagine situations in which
the timer elapsed event and the ACK event arrive so closely together
that both are put on the message queue. The end result of this would be
that the state machine would send the next data packet in response to
the ACK, then responding to the old timer elapsed event, assume that
the 20ms for the *next* data packet has already expired and send the
next data packet prematurely. This is hard to explain, and I'm not sure
I've made this very clear.
In researching this tonight, I think what I need is some sort of timed
priority queue. This takes the timer management out of the hands of the
state machine. It simply responds to events generated by the timed
priority queue. Each enqueued timed event would have a unique ID. In
response to a timeout event, the state machine would check to see if the
event's ID is for a data packet it has already sent. If so, it can
ignore it.
Does this make sense?
I'm not sure what I'm missing, but I'd like my code to me more robust
than this. Is there an additional state that would prevent the above
scenerio? I was thinking about giving each timer event a unique ID as
one approach. When the state machine consumes a timer event, the ID
must be valid for the next message or it is ignored.
The ID approach is good and will work for the mechanism you have
described. I would use a sequential message number for the ID so all
I would have to do is make sure the message ready to send has an ID
one greater than the ACK I have just received.
That's a good idea.
What is more fundamental to the design is why you are taking this
approach in the first place. Hopefully thinking about the above
questions will help.
I appreciate your response, thanks. I'm trying to implement the protocol
as robustly as I can. I'm just finding the timeouts to be a little
tricky. Some of this is new ground for me.
.
- References:
- Time outs and state machines
- From: Leslie Sanford
- Re: Time outs and state machines
- From: Robert Oliver
- Time outs and state machines
- Prev by Date: Re: Time outs and state machines
- Next by Date: Re: Time outs and state machines
- Previous by thread: Re: Time outs and state machines
- Next by thread: Re: Time outs and state machines
- Index(es):
Relevant Pages
|