Forum: Ruby local interprocess communication ideas.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
055a7035faeedafb224a536ff3a18e87?d=identicon&s=25 James Mills (Guest)
on 2007-01-17 23:30
(Received via mailing list)
I am currently developing a simple controller.  It consists of a GUI
(C++) and a controller (ruby) that talks to a serial port.

Now, I understand that this can (or maybe should) be combined into a
single app that communicated directly with the serial port.  However,
I wouldn't have the opportunity to ask this question if that were the
case!

So, I have an embedded ARM proc with about 200MHz, and I want this app
to feel as responsive as possible.  The GUI and controller will both
run on this machine.  When a button on the GUI is pressed, the command
is sent to the controller, the controller sends a command out of the
serial port, and an action is taken.

Let's assume that all parts not including the IPC between the GUI and
the controller are working fine. My question deals with the local IPC
between the GUI and the controller.

I really like XML/RPC.  It is really easy and straightforward in Ruby,
and has worked really well in the past for network-based distributable
apps.  However, in this case I can see how the overhead of XML and
"IP" communication might make the app feel too slow (It would be bound
to localhost, of course).

I would really like to use a standard protocol, preferably one
natively implemented in ruby already.  I just need it to be fast...

So, with all of that info, what does the community recommend for a
lightening fast interprocess communication method?

Feel free to tell me that XML/RPC is fast enough, if it is...

Thanks!

~james
46ec10622045f5671a1067865566f13c?d=identicon&s=25 Ben Giddings (Guest)
on 2007-01-18 00:07
(Received via mailing list)
On Jan 17, 2007, at 17:30, James Mills wrote:
> So, I have an embedded ARM proc with about 200MHz, and I want this app
> to feel as responsive as possible.  The GUI and controller will both
> run on this machine.  When a button on the GUI is pressed, the command
> is sent to the controller, the controller sends a command out of the
> serial port, and an action is taken.


How responsive are we talking about here?  Do you need "twitch" video
game type responsiveness (tens of ms) or something less?  Unless you
need twitch video game responsiveness, I'm pretty sure anything over
the local loopback would be fast enough.  I've written CGIs that ran
on the webserver of an ARM-based embedded device, and despite the
overhead of a *real* network between me and them, they seemed very
responsive.

If you need tens-of-ms type responsiveness, you might want to use
some shared memory.  This couldn't be done natively in Ruby, but it
would be pretty easy to write some simple C, write a Ruby extension,
and use it that way.

Keep in mind that in my experience, you'll never be able to get any
better than say 20ms responsiveness, since that's the task-switching
overhead inherent in using Linux (and I assume other OSes would be
similar).  You *could* get faster by writing kernel extensions, but
that's even further from a pure Ruby implementation.

Ben
4e8d94859927eab3b50486d21249c068?d=identicon&s=25 Paulo Köch (Guest)
on 2007-01-18 01:17
(Received via mailing list)
On 2007/01/17, at 23:06, Ben Giddings wrote:
> On Jan 17, 2007, at 17:30, James Mills wrote:
>> So, I have an embedded ARM proc with about 200MHz, and I want this
>> app to feel as responsive as possible.
>
> I've written CGIs that ran on the webserver of an ARM-based
> embedded device, and despite the overhead of a *real* network
> between me and them, they seemed very responsive.

Be lazy! Write a XML/RPC version (if you think it's not a lot of
work), and only think about more "complicated" IPC if it's not
enough. You can always blame Ben Giddings or me! =P

Paulo Jorge Duarte
Köchpaulo.koch@gmail.com
0d433534e5df0891cff1f5e4dec8efe6?d=identicon&s=25 ian dacek (Guest)
on 2007-01-18 06:06
(Received via mailing list)
James Mills wrote:
> So, with all of that info, what does the community recommend for a
> lightening fast interprocess communication method?
>
Depending on the size of your messages, why not use UDP and your own
simple message format? You'd eliminate the overhead of TCP, not to
mention the bloat of XML. You could send the data for the serial port
with a header or Ruby code prepended, then interpret the header or eval
the code...

-ian
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2007-01-18 15:48
(Received via mailing list)
On Jan 18, 2007, at 12:06 AM, ian dacek wrote:

> James Mills wrote:
>> So, with all of that info, what does the community recommend for a
>> lightening fast interprocess communication method?
>>
> Depending on the size of your messages, why not use UDP and your
> own simple message format? You'd eliminate the overhead of TCP, not
> to mention the bloat of XML. You could send the data for the serial
> port with a header or Ruby code prepended, then interpret the
> header or eval the code...

The TCP overhead is there for a purpose.  UDP is an unreliable
protocol.  Packets may get dropped, duplicated, or reordered.  If
your application is OK with that, great, but if not then you are
going spend a lot of time designing what basically amounts to TCP
(sequence numbers, retransmission strategies, and so on).


Gary Wright (Radar)
91e1fb8bd265b7629491ab64c42f0906?d=identicon&s=25 Reid Thompson (Guest)
on 2007-01-18 16:59
(Received via mailing list)
James Mills wrote:
> run on this machine.  When a button on the GUI is pressed, the command
> "IP" communication might make the app feel too slow (It would be bound
> Thanks!
>
> ~james
>
what OS?
0d433534e5df0891cff1f5e4dec8efe6?d=identicon&s=25 ian dacek (Guest)
on 2007-01-19 16:31
(Received via mailing list)
gwtmp01@mac.com wrote:
>> with a header or Ruby code prepended, then interpret the header or
>> eval the code...
>
> The TCP overhead is there for a purpose.  UDP is an unreliable
> protocol.  Packets may get dropped, duplicated, or reordered.  If your
> application is OK with that, great, but if not then you are going
> spend a lot of time designing what basically amounts to TCP (sequence
> numbers, retransmission strategies, and so on).
That's generally true of UDP, especially between two remote hosts
bridged by a router.

However, going between two ports on the localhost should actually net
something along the lines of a memory copy, depending on the
behind-the-scenes networking implementation.

-ian
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2007-09-25 22:31
(Received via mailing list)
On Jan 18, 2007, at 8:14 PM, ian dacek wrote:
> That's generally true of UDP, especially between two remote hosts
> bridged by a router.

Memory allocation/starvation issues can cause lost UDP packets even
to/from a single host. I'll bet there are other possibilities.  It is
just a bad starting point to make the assumption that it will be
reliable in your particular circumstance.  Of course there are
circumstance in which in will work anyway.

If you know it is to/from the same host then Unix domain sockets
might be an option.

In any case, I just wanted everyone reading that thread to be aware
of the caveats of UDP-based protocols.

Gary Wright
055a7035faeedafb224a536ff3a18e87?d=identicon&s=25 James Mills (Guest)
on 2007-09-25 23:06
(Received via mailing list)
Thanks to everyone who had ideas on this one.  I love mailing lists.

I ended up using popen3 to launch the GUI from within the ruby code.
I created a listening thread on the stdout handle, and acted upon
anything that came in.  This has several advantages for this project.

* The GUI is really dumb.  All it does is generate a three-letter
message to stdout when a button is pressed or released.

* All of the prep code and routines needed to set up the serial port
comms and other prop data can be done before the GUI is launched.

* The GUI could be tested independently from the ruby portion.  This
was good since it was developed remotely.

In this scenario, popen3 was perfect!  It was really fast, and it is
built in.

Thanks again!

~james
This topic is locked and can not be replied to.