"Conversations" and coroutines

  • Thread starter Levin Alexander
  • Start date
L

Levin Alexander

Hi,

I am trying to write a some code that expresses a series of =20
Commands/Responses over a serial link.

In pseudocode, this is what I want to accomplish:

conv =3D Conversation.new(connection) { |x|
x.transmit:)init)
x.wait_for:)ok)
x.transmit:)get_user_input)
x.wait_for:)user_data) { |message| response =3D message.text }
puts response
rescue TimeoutException =3D> e
x.retry if x.attempts < 3
}
conv.start

I suppose that something like that can be done with continuations and =20
coroutines (which I have never used before) Especially =20
<http://www.all-thing.net/Ruby/coroutines.html> looks useful.

I would really appreciate any advice on how to best implement all this. =
=20
Are there some projects/libraries that do something similar?

The interface I made up above could probably also be improved a lot and =20
I'd appreciate your thoughts and suggestions.

Thank You,
Levin
 
J

Joel VanderWerf

Levin said:
Hi,

I am trying to write a some code that expresses a series of
Commands/Responses over a serial link.

In pseudocode, this is what I want to accomplish:

conv = Conversation.new(connection) { |x|
x.transmit:)init)
x.wait_for:)ok)
x.transmit:)get_user_input)
x.wait_for:)user_data) { |message| response = message.text }
puts response
rescue TimeoutException => e
x.retry if x.attempts < 3
}
conv.start

I'm guessing #start runs the block? Why not

Thread.new {conv.start}

Or does the block get executed during Conversation.new, which just
queues up all the commands so that start can call them in order later?
 
L

Levin Alexander

Joel VanderWerf said:
I'm guessing #start runs the block? Why not

Thread.new {conv.start}

I am pretty sure that I need Threads, but I think a single =20
'receiver'-Thread inside the connection instance should be enough.

My main problem at this point is that I don't know how I want the final =20
result to *look* like.
Or does the block get executed during Conversation.new, which just
queues up all the commands so that start can call them in order later?

No, the "conversation" should be an arbitrary program.

My current attempts wrap around an instance of IO, like so:

# Connection wraps protocol details like a notion of "Packets" and
# generates events if specific messages arrive
connection =3D Connection.new( f =3D Tempfile.new("example") )

# Add a Packet named :init that can be sent by
# calling "connection.send_packet:)init)"
connection.add_sender:)init, Packet.create:)data_format =3D> "INIT") )

# Add an event called :eek:k that is generated whenever a packet
# starting with the letter "O" is received
connection.add_receiver:)ok, Packet.create:)header =3D> [?O]) )

# Register an event handler
connection.on_receive:)ok) { |m| puts "received message: OK" }

Given that I could probably do this:

# Resumable from <http://www.all-thing.net/Ruby/coroutines.html>

conversation =3D Resumable.new { |r|
connection.on_receive:)ok) { r.resume if r.suspended? }
connection.send:)init)
r.suspend
puts "Got an answer!"
}

...
connection.start # start sending/receiving data
conversation.call
...

That's not very pretty though

-Levin
 
M

Mark Probert

Hi ..

Hi,

I am trying to write a some code that expresses a series of
Commands/Responses over a serial link.
I think that the "serial link" part is important. How does the
underlying interface present its data? Interrupt or polled? And the
host, does it block on serial data?

If everything is inherently serial, then there is not much to be gained
with threads. Are you expecting to do the equivalent of receive a
packet then process it? If so, then having a polling thread that puts
its processed data in a buffer seems to make sense.

Coroutines are a funny thing. They are kind of like multitasking when
there is no other choice (a la FORTH or Modula-2, where I think they
came from). Ruby threads will buy you more that procedure swapping, I
think.

Just my $0.02

Regards,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top