Skip to main content

Concurrent use of embedded Ruby in Java (using JRuby)

Posted by boneill42 on November 30, 2011 at 11:28 AM PST

Last night, I was finishing up the map/reduce capabilities within Virgil. We hope to allow people to post ruby scripts that will then get executed over a column family in Cassandra using map/reduce. To do that, we needed concurrent use of a ScriptEngine that could evaluate the ruby script. In the below code snippets, script is a String that contains the contents of a ruby file with a method definition for foo.

First, I started with JSR 223 and the ScriptEngine with the following code:

public static final ScriptEngine ENGINE = new ScriptEngineManager().getEngineByName("jruby");

ScriptContext context = new SimpleScriptContext();

Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

bindings.put("variable", "value");

ENGINE.eval(script, context);

That worked fine in unit testing, but when used within map/reduce I encountered a dead-lock of sorts. After some googling, I landed in the Redbridge documentation. There I found that jruby exposes a lower-level API (beneath JSR223) that exposes concurrent processing features. I swapped the above code, for the following:


this.rubyContainer = new ScriptingContainer(LocalContextScope.CONCURRENT);

this.rubyReceiver = rubyContainer.runScriptlet(script);

container.callMethod(rubyReceiver, "foo", "value");

That let me leverage a single engine for multiple concurrent invocations of the method foo, which is defined in the ruby script.

This worked like a charm.

 

Related Topics >>