Posted by Chuck Vose
Mon, 07 Jan 2008 18:11:00 GMT
Slight typo in the code fixed: 2008-01-08
Toshiyuki and I have released a new gem called rbridge which allows us to execute functional, side-effect free, concurrent code directly in Ruby regardless of the version by using Erlang as a processor. This includes using the Mnesia distributed database and ETS/DETS.
To try it out please follow these steps:
1. Download Erlang for your os. Windows has binaries and OS X can be configured with `./configure—prefix=/opt/local` to make MacParts happy. I haven’t yet tried it with Linux but the default configure options should be okay.
2. Download the rbridge gem. `sudo gem install rbridge`
3. Start the rulang server in Erlang on port 9900. Change dir to the gem directory which is usually /usr/local/lib/ruby/gems/1.8/gems/rbridge-0.1/lib and run sudo erlc rulang.erl. Enter the Erlang shell by typing erl. Finally, start the server with rulang:start_server(9900). (There’s a dot at the end of the command).
4. Require rubygems and rbridge in your code and create a new connection to the rulang server. This is the simplest bit of inline code I can think of but there is a lot more we can do: asynchronous access and ruby-style syntax specifically.
require 'rubygems'
require 'rbridge'
@r = RBridge.new(nil, 'localhost', 9900)
puts @r.erl('10*10.')
To read more check out the documentation on ruby-mnesia.rubyforge.org.
Aside: Toshiyuki Hirooka found me. Thank you to everyone that helped search and offered to translate for us. I’m constantly impressed by the support from the Ruby community.
Posted in Ruby, Erlang | Tags Erlang, gems, rbridge, Ruby, rulang | no comments
Posted by Chuck Vose
Sat, 05 Jan 2008 00:54:00 GMT
FEATURES:
Allows use of Erlang code within Ruby
Changes:
v0.1 / 2008-01-04 (vosechu)
1 major enhancement
- Allows many-lined Erlang commands when using the Erlang class for direct
access.
3 minor enhancements
- Revised error checking to allow custom resolution
- stop_server/0 now shuts down any servers running in an erl shell
- created tests to run with RSpec and autotest (erl server must be running
on port 9900).
3 other changes
- Forked onto rubyforge complete with rdocs, gem, etc.
- Translated some comments into english as well as the README
- Packaged explicitly with gpl documentation
Posted in Ruby, Mnesia, Erlang | Tags bridge, Erlang, Ruby, rulang | no comments
Posted by Chuck Vose
Thu, 03 Jan 2008 17:17:00 GMT
Rulang was giving me a lot of trouble with regards to multi-line commands and complex commands in general. After hacking on it for a while I’ve developed a patch that will allow ruby code such as the following:
require 'rulang'
@mnesia = RulangBridge::Erlang.new("localhost", 9900)
def find
@mnesia.eval(<<-EOF
QH = qlc:q([X || X <- mnesia:table(shop)]),
F = fun() -> qlc:eval(QH) end,
{atomic, Val} = mnesia:transaction(F),
Val.
EOF
)
end
puts find
PATCH
diff -u Desktop/rulangbridge/rulang.erl Current Schoolwork/Project/mnesia/rulang_test/rulang.erl
--- Desktop/rulangbridge/rulang.erl 2007-05-17 20:25:50.000000000 -0700
+++ Current Schoolwork/Project/mnesia/rulang_test/rulang.erl 2008-01-03 10:12:05.000000000 -0800
@@ -30,11 +30,15 @@
handle_connection(Socket) ->
- Reason = (catch communication(Socket)),
- gen_tcp:send(Socket, io_lib:format("Error: ~w~n", [Reason])),
+ try communication(Socket)
+ catch
+ error:Reason ->
+ {gen_tcp:send(Socket, io_lib:format("Error: ~p~n", [Reason]))}
+ end,
ok = gen_tcp:close(Socket).
+% Try to evaluate the code submitted throwing an exception if the evaluation
+% doesn't work. Return the code submitted.
communication(Socket) ->
{ok, Binary} = gen_tcp:recv(Socket, 0),
{ok, Result} = eval(binary_to_list(Binary)),
@@ -43,9 +47,9 @@
eval(Expression) ->
- {ok, Scanned, _} = erl_scan:string(Expression),
- {ok, [Parsed]} = erl_parse:parse_exprs(Scanned),
- {value, Result, _} = erl_eval:expr(Parsed, []),
+ {done, {ok, Scanned, _}, _} = erl_scan:tokens([], Expression, 0),
+ {ok, Parsed} = erl_parse:parse_exprs(Scanned),
+ {value, Result, _} = erl_eval:exprs(Parsed, []),
{ok, Result}.
diff -u Desktop/rulangbridge/rulang.rb Current Schoolwork/Project/mnesia/rulang_test/rulang.rb
--- Desktop/rulangbridge/rulang.rb 2007-05-24 10:42:22.000000000 -0700
+++ Current Schoolwork/Project/mnesia/rulang_test/rulang.rb 2008-01-03 10:02:19.000000000 -0800
@@ -79,7 +79,7 @@
def eval(command)
socket = TCPSocket.new(@host, @port)
socket.write(command)
- socket.gets # ...?
+ socket.read # ...?
end
Posted in Ruby, Mnesia, Erlang | Tags Erlang, Mnesia, Ruby, rulang | no comments
Posted by Chuck Vose
Wed, 02 Jan 2008 22:25:00 GMT
Owing to the complexities of building a Rails adapter for Mnesia I’ve been looking into using a Ruby to Erlang bridge and have looked at the various projects that seem to be available and want to share my comments on how each is stacking up so far.
Rebar
Rebar was announced on 2007-04-20 and has since never surfaced to the public as far as his blog and Google are concerned. The code looked to be among the easiest to understand but is thankfully very similar to the Japanese RulangBridge below. The existence of the Japanese project could explain why Tom Werner never finished the project but that’s merely a guess.
Erlectricity
Erlectricity by Scott Fleckenstein was the first project I really tried out and I am impressed by some aspects and disappointed by others. On one hand it was easy to obtain being hosted on RubyForge and Google Code and works well at using Ruby from Erlang. On the other hand it comes with no documentation or rdocs outside of two uncommented examples.
I could never figure out a way to get it to bridge Erlang commands from Ruby but there may be a way that I’m missing; I have to admit I’ve not asked Scott about whether this code can go both ways or not.
So if you need something that Ruby does well but Erlang doesn’t then this may be your project. The second example uses the bridge to generate a gruff graph from Erlang which seems like it’ll come in handy for a lot of people.
Outside of documentation I’m concerned about whether the bridge can handle asynchronous requests from Erlang. From first glance it doesn’t seem like there’s any blocking and each Erlang thread calls the script directly instead of central blocking thread so I’m guessing that there’s no concurrency built in; something that we would have to work with if we were to use this bridge for a many-threaded project.
RulangBridge
RulangBridge by Toshi Hirooka (?) is a Japanese project allowing Ruby to use Erlang functions. Google’s translation allows us to read the usage instructions and browse the code which has allowed me to start using it in earnest to build the Ruby to Mnesia bridge.
My first impressions are that the bridge is that it is a little immature despite the >1.0 release number. The example code is excellent (if in Japanese) but it isn’t packaged in a gem or hosted on RubyForge and doesn’t have a way to auto-start an Erlang server. Furthermore, using only the built in classes we have to make the choice of asynchronicity or complicated/multi-module code.
Of course the raw class (called Erlang) can be made asynchronous by wrapping it in a Thread.new which is essentially what the Rulang wrapper class does, but it would be nice to have this built-in. Putting the asynchronous switch in the wrapper class is fine but the wrapper class suffers from a desire to make the Erlang calls feel like ruby and therefore makes calling complicated code impossible through the wrapper and thus makes the asynchronous aspect moot also.
The last concern I have is that each class must connect to a node explicitly rather than being able to automatically find and balance between nodes. In order to be happy with the adapter we’ll have to figure out how to load-balance or make Erlang do it for us.
Conclusion
For the purposes of the the Ruby to Mnesia Adapter I believe that RulangBridge will be sufficient but Erlectricity definitely has its purposes in the Erlang community. Despite some concerns and drawbacks both are usable code and could easily move forward with a little love from the community or follow-up versions by the owners.
Any project involving Erlang and Ruby will have to deal extensively with concurrency. Ideally it would be nice to see a broker model between the two that supports communication in both directions and deals with concurrency issues and load-balancing transparently. Until that happens we’ll have to work with Erlectricity and Rulang and love the creators for their hard work.
Posted in Ruby, Mnesia, Programming, Erlang | Tags bridge, Erlang, Ruby | 3 comments | no trackbacks