[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

state machine in ruby

snacktime

9/8/2006 5:40:00 PM

So I'm refactoring a very ugly piece of client code that needs to
implement some fairly complicated error correction over a line based
tcp protocol. There are about 10 different error scenarios I have to
detect and respond differently to. Think error correction over serial
lines, that's actually where this was derived from and now it's
layered over a tcp connection. Most of the scenarios involve several
back and forth messages between client and host. Most of the
scenarios are very similar, so if you think of it as a tree I might
not know what scenario I am dealing with until I've gotten 2-3 levels
deep, and at any point in the tree I need to know where I am and what
the possible branches are I can take based on the next response from
the host.

Any suggestions on how to implement this cleanly?

Chris

17 Answers

Robert Klemme

9/8/2006 6:33:00 PM

0

snacktime <snacktime@gmail.com> wrote:
> So I'm refactoring a very ugly piece of client code that needs to
> implement some fairly complicated error correction over a line based
> tcp protocol. There are about 10 different error scenarios I have to
> detect and respond differently to. Think error correction over serial
> lines, that's actually where this was derived from and now it's
> layered over a tcp connection. Most of the scenarios involve several
> back and forth messages between client and host. Most of the
> scenarios are very similar, so if you think of it as a tree I might
> not know what scenario I am dealing with until I've gotten 2-3 levels
> deep, and at any point in the tree I need to know where I am and what
> the possible branches are I can take based on the next response from
> the host.
>
> Any suggestions on how to implement this cleanly?

It seems you have answered it in the subject already, don't you? One other
solution came to mind, something like a decision tree when you mentioned
that you need several steps to determine what's going on. A bit like a mini
expert system. Only 0.01 EUR today...

Kind regards

robert

Francis Cianfrocca

9/8/2006 6:44:00 PM

0

snacktime wrote:
> So I'm refactoring a very ugly piece of client code that needs to
> implement some fairly complicated error correction over a line based
> tcp protocol. There are about 10 different error scenarios I have to
> detect and respond differently to. Think error correction over serial
> lines, that's actually where this was derived from and now it's
> layered over a tcp connection. Most of the scenarios involve several
> back and forth messages between client and host. Most of the
> scenarios are very similar, so if you think of it as a tree I might
> not know what scenario I am dealing with until I've gotten 2-3 levels
> deep, and at any point in the tree I need to know where I am and what
> the possible branches are I can take based on the next response from
> the host.
>
> Any suggestions on how to implement this cleanly?
>
> Chris

For clues to a possible approach, look at the HTTP client implementation
in EventMachine. Sync to SCM, and it's in version_0/lib/protocols.

You can get as crazy with this kind of thing as you want, but if your
requirements are simple you can get away with a variable that indicates
the current protocol state. Then a simple case statement will constrain
your possible paths. It's quite rare for a network protocol to be more
complicated than that. But if yours is, consider using a LALR(1)
grammar.

--
Posted via http://www.ruby-....

vidar

9/8/2006 7:16:00 PM

0


snacktime wrote:
> So I'm refactoring a very ugly piece of client code that needs to
> implement some fairly complicated error correction over a line based
> tcp protocol. There are about 10 different error scenarios I have to
> detect and respond differently to. Think error correction over serial
> lines, that's actually where this was derived from and now it's
> layered over a tcp connection. Most of the scenarios involve several
> back and forth messages between client and host. Most of the
> scenarios are very similar, so if you think of it as a tree I might
> not know what scenario I am dealing with until I've gotten 2-3 levels
> deep, and at any point in the tree I need to know where I am and what
> the possible branches are I can take based on the next response from
> the host.
>
> Any suggestions on how to implement this cleanly?

A state machine is fundamentally a set of states with associated
actions (if any) and transitions. A transition consists of a criteria
and a state to transition to. How you model that depends on how much
flexibility you need. If the state machine is fairly fixed you could
just as well implement it as a class. Something like this for example:

class StateMachine
def initialize
@state = :some_state # Starting state of the machine


end

def some_state
# Carry out actions for this state here.


result = :foo # Just a dummy result

# Transitions:


case result
when :foo : @state = :some_other_state
# more transitions ...


else @state = :stop
end
end

def some_other_state
# Action goes here
# Transition
@state = :stop
end

# Doesn't have to do this, but it might be
# nice to have a simple way of passing data
# between the state machine and a block.
# Perhaps use the block to do any IO etc.
# so the state machine doesn't need to know
# anything about it's environment
def each
while @state != :stop
send @state
yield self,@state
end
end
end

StateMachine.new.each { |sm,state| p state }

If you need something more dynamic, it would be easy enough to store
the transitions in a Hash of hash'es { :state_1 => {
:transition_criteria_1 => :state_2, :transition_criteria_2 => :state_3
} }.

Vidar

Ara.T.Howard

9/8/2006 8:22:00 PM

0

Francis Cianfrocca

9/8/2006 8:53:00 PM

0

On 9/8/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>
>
> harp:~ > cat a.rb
>
> require 'fsm'
>
> FSM.system do
>
> fsm{
> states %w( empty full )
> transition 'filling', 'empty' => 'full'
> transition 'emptying', 'full' => 'empty'
> }
>
> observer{
> on_entry 'empty' do
> puts 'became empty.'
>
> transition 'empty', 'filling' do
> puts 'filling...'
> sleep 1
> end
> end
>
> on_entry 'full' do
> puts 'became full.'
>
> transition 'full', 'emptying' do
> puts 'emptying...'
> sleep 1
> end
> end
> }
>
> start
> end
>
> STDIN.gets
>


Reading this, I kept trying to figure out how this is different from
plain old yacc, then I realized you have no lookahead capability. What
kind of situations have you used this in? I don't understand Chris'
example enough yet to decide if it constitutes a regular language or
something more.

Mechanically dealing with comms protocols is a pretty interesting
subject, although in general the more recent ones aren't terribly
complicated. (The practical subset of HTTP isn't bad; SIP isn't bad;
SMTP is a bear; XML is ambiguous in at two places I know of.) I often
end up just writing recursive-descent parsers that expose their
internal state and use a pushback buffer so they can be restarted.

Ara.T.Howard

9/8/2006 9:05:00 PM

0

snacktime

9/8/2006 10:04:00 PM

0

Ya I hesitated to post that as it was pretty hard to read. You can
actually read the spec at http://www.fdms.... It's the Visa
protocol. Not that you would want to, but that's an easier way to see
it if you do.

What's really scary though is my original implementation of this from
9 years ago in perl that uses modems.

Martin DeMello

9/9/2006 10:15:00 AM

0

On 9/8/06, snacktime <snacktime@gmail.com> wrote:
> So I'm refactoring a very ugly piece of client code that needs to
> implement some fairly complicated error correction over a line based
> tcp protocol.

Give smc.sourceforge.net a look

martin

Ara.T.Howard

9/9/2006 3:06:00 PM

0

Sean O'Halpin

9/9/2006 3:35:00 PM

0

On 9/9/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>
> what's AMQP ??
>
Possibly Advanced Message Queuing Protocol - see
http://en.wikipedia.org/wiki/Advanced_Message_Queuin... and
http://imatix.com/amqp/amqp0-8-specifi....

(Does anyone here believe in morphic resonance? I've just been
researching this and state machines. Spooky.)

Regards,
Sean