Using YAML for inter-process communication - anything built-in?


#1

Hi,

I’m just wondering - I implemented something (http://github.com/thbar/
petite-lettre/tree/master) I believe probably already exists, can
anyone tell me if it does ?

I’m using YAML to communicate using stdin/stdout between a Ruby MRI
process and a JRuby process (I will soon use it to communicate between
IronRuby and JRuby).

The parent process launches the child using:

PetiteLettre.call(“ruby child_program.rb”, { :command
=> :start_sale, :isbn => “1234567”, :price => 12.4 })

and the child responds with:

PetiteLettre.receive do |message|
response = {}
if message[:command] == :start_sale
# do something here
raise “Price is too low” if message[:price] < 15.0
response[:status] = “OK”
response[:transaction_id] = “1235”
else
raise “Unknown command ‘#{message[:command]}’”
end
response
end

If something already exists in Ruby to do that this way, I’d like to
know about it.

Any idea ?

Thibaut


#2

On 02.03.2009 13:14, Thibaut Barrère wrote:

The parent process launches the child using:
raise “Price is too low” if message[:price] < 15.0

Any idea ?

I am not sure about portability of Marshal across Ruby implementations.
In case it is given you could achieve similar results using DRb.

Kind regards

robert


#3

Hi Robert,

I am not sure about portability of Marshal across Ruby implementations.
In case it is given you could achieve similar results using DRb.

that’s a good point. I’ll try that if I stick with two ruby parties.

– Thibaut


#4

Thibaut Barrère wrote:

If something already exists in Ruby to do that this way, I’d like to
know about it.

I came across a YAML-RPC once upon a time; you could try looking for it.

I’d avoid YAML as much as possible, as it’s horribly broken; certainly
useless for mere humans writing YAML anyway.

irb(main):001:0> require “yaml”
=> true
irb(main):002:0> YAML.load(“foo:bar\nbaz:”)
=> “foo:bar baz:”
irb(main):003:0> YAML.load(“foo:bar\nbaz:\n”)
=> {“foo:bar baz”=>nil}
irb(main):004:0> YAML.load(“foo:bar\nbaz:bap\n”)
=> “foo:bar baz:bap”
irb(main):005:0> YAML.load(“foo: bar\nbaz:bap\n”)
ArgumentError: syntax error on line 2, col -1: ' from /usr/local/lib/ruby/1.8/yaml.rb:133:inload’
from /usr/local/lib/ruby/1.8/yaml.rb:133:in `load’
from (irb):5
irb(main):006:0> YAML.load(“foo: bar\nbaz: bap\n”)
=> {“baz”=>“bap”, “foo”=>“bar”}

There are also examples which have been posted to this list showing
objects serialised to YAML and immediately back again, ending up with
different content.

But I sympathise if you want to do something DRb-like, but between two
different Ruby implementations. XMLRPC/JSON won’t give you full Ruby
object serialisation, and SOAP is too horrible to contemplate.


#5

Gary Y. wrote:

You’re missing the ‘—’ header in these examples. YAML may behave
more robustly with the header.

Nope, it’s exactly the same:

irb(main):001:0> require “yaml”
=> true
irb(main):002:0> YAML.load("—\nfoo:bar\nbaz:")
=> “foo:bar baz:”
irb(main):003:0> YAML.load("—\nfoo:bar\nbaz:\n")
=> {“foo:bar baz”=>nil}
irb(main):004:0> YAML.load("—\nfoo:bar\nbaz:bap\n")
=> “foo:bar baz:bap”
irb(main):005:0> YAML.load("—\nfoo: bar\nbaz:bap\n")
ArgumentError: syntax error on line 3, col -1: ' from /usr/lib/ruby/1.8/yaml.rb:133:inload’
from /usr/lib/ruby/1.8/yaml.rb:133:in `load’
from (irb):5
irb(main):006:0> YAML.load("—\nfoo: bar\nbaz: bap\n")
=> {“baz”=>“bap”, “foo”=>“bar”}

Check out FastYAML on github. It’s way faster than YAML, doesn’t use
Syck, and is way more robust than YAML.

But is apparently not available as a gem.

$ gem sources
*** CURRENT SOURCES ***

http://gems.rubyforge.org/
http://gems.github.com/
$ sudo gem search --remote YAML

*** REMOTE GEMS ***

feedtools-cache-yaml (0.0.2)
kakutani-yaml_waml (0.3.0)
markbates-yamler (0.1.0)
RbYAML (0.2.0)
ya2yaml (0.26)
yamlconfig (0.1.2)
yamler (0.1.0)
yamlrpc (1.0.4)
yamltest (0.5.1)
$


#6

Hi Brian, Gary,

yeah I’m only simple YAML, and it seems to work for me for what I’m
doing. I’ll definitely try to have a C# or Java client consume these
and see what happens.

Thanks for FastYAML too, interesting.

cheers!

– Thibaut


#7

You’re missing the ‘—’ header in these examples. YAML may behave
more robustly with the header.

Check out FastYAML on github. It’s way faster than YAML, doesn’t use
Syck, and is way more robust than YAML.

-Gary


#8

Thibaut Barrère wrote:

Hi Brian, Gary,

yeah I’m only simple YAML, and it seems to work for me for what I’m
doing. I’ll definitely try to have a C# or Java client consume these
and see what happens.

Thanks for FastYAML too, interesting.

One other thought: if it’s simple, look at JSON. It’s easy to extend to
serialise arbitrary Ruby objects.

YAML can do things like handling multiple references to the same object,
but it sounds like you don’t need that level of sophistication.


#9

One other thought: if it’s simple, look at JSON. It’s easy to extend to
serialise arbitrary Ruby objects.

I’ve been thinking about that. One point that made me choose YAML
instead is that YAML support is built-in in STD ruby, where JSON is
not (AFAIK).

As well from my experience YAML is better covered than JSON on other
platforms (such as .Net)…

That’s why I choosed YAML for the moment.

YAML can do things like handling multiple references to the same object,
but it sounds like you don’t need that level of sophistication.

I don’t need this for the moment, but it may come :slight_smile:

cheers and thanks for the feedback, appreciated

– Thibaut