Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > state machine in ruby

Reply
Thread Tools

state machine in ruby

 
 
snacktime
Guest
Posts: n/a
 
      09-08-2006
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

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      09-08-2006
snacktime <(E-Mail Removed)> 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

 
Reply With Quote
 
 
 
 
Francis Cianfrocca
Guest
Posts: n/a
 
      09-08-2006
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-forum.com/.

 
Reply With Quote
 
Vidar Hokstad
Guest
Posts: n/a
 
      09-08-2006

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

 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      09-08-2006

sorry not to include orig message - the text was totally fubar and hosed my
mailer...

anyone.

this is incomplete, but i made a little finite state machine lib and dsl. it
even includes tools to vizualize if you have dot installed. it's here

http://rubyforge.org/projects/codeforpeople/
http://codeforpeople.org/lib/ruby/

an example


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


harp:~ > ruby a.rb
became empty.
filling...
became full.
emptying...
became empty.
filling...
became full.
emptying...
became empty.
filling...


sorry, no docs yet


-a
--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

 
Reply With Quote
 
Francis Cianfrocca
Guest
Posts: n/a
 
      09-08-2006
On 9/8/06, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> 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.

 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      09-08-2006
On Sat, 9 Sep 2006, Francis Cianfrocca wrote:

> 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?


reprocessing 30 satellite years of data from a tape archive... there are
several steps that are async and, though it may not be obvious from the above
examples, the fsm class puts every thing in Threads and communcates via
Queues...

so, basically, it makes it safe for multiple threads to be doing work and
directiing their actions via a shared state machine....


-a
--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

 
Reply With Quote
 
snacktime
Guest
Posts: n/a
 
      09-08-2006
Ya I hesitated to post that as it was pretty hard to read. You can
actually read the spec at http://www.fdms.com/specs. 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.

 
Reply With Quote
 
Martin DeMello
Guest
Posts: n/a
 
      09-09-2006
On 9/8/06, snacktime <(E-Mail Removed)> 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

 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      09-09-2006
On Sat, 9 Sep 2006, Francis Cianfrocca wrote:

>> http://rubyforge.org/projects/codeforpeople/
>> http://codeforpeople.org/lib/ruby/

>
> Ugh. This is what sucks about hanging out with all you smart people, you
> guys have got me thinking about this now. Ara, you're talking about a FSM
> processor here,


yes. it's state machine __system__: the machine and the system to process it
in an async way...

> but have you thought about augmenting it to handle context-free grammars?


nope. but i'd take any and all patches!

> Ideally I'd like to be able to define protocols textually, in BNF-like or
> yacc-like form.


seen this

http://raa.ruby-lang.org/project/fsmgen/

i haven't used it - looked interesting...

> And given that text, mechanically generate a state machine that would be
> restartable so it could be event-driven. And the scanner would be pretty
> funky too, it would have to be able to generate a token that means "not
> enough input to scan a complete token, go to sleep now."


naw, that's easy. just do

consumer.q.push token_bits
consumer.q.push token_bits
consumer.q.push token_bits
consumer.q.push token_done

and the consumer is automatically sleeping as tokens arrive partially.

> I've just been in the middle of implementing AMQP the old-fashioned way (by
> hand) so this is timely.


what's AMQP ??

-a
--
what science finds to be nonexistent, we must accept as nonexistent; but what
science merely does not find is a completely different matter... it is quite
clear that there are many, many mysterious things.
- h.h. the 14th dalai lama

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
State machine - Vending machine - strange behaviour fenster VHDL 3 12-23-2011 09:53 AM
How to print a state flow graph for a state machine using Xilinx ISE or ModelSim Weng Tianxiang VHDL 3 07-25-2006 01:19 PM
What is the state of state machine after power-up without reset conditions Weng Tianxiang VHDL 7 11-25-2003 06:24 PM
State machine: how to stay in a state? David Lamb VHDL 1 09-15-2003 05:24 PM



Advertisments