I’m using JRuby Embed API in my Java code, where I create an object
graph that is processed and then passed to Ruby code. This graph
contains e.g. RubyHash and RubyArray objects.
The Java code runs in a multi-threaded environment and I’d like to
make sure I’m not introducing any race conditions.
The application instantiates a single ScriptingContainer object, which
is shared among different threads.
sc = new ScriptingContainer(LocalContextScope.CONCURRENT);
RubyHash/Array objects are instantiated as follows:
RubyHash rh = new RubyHash(sc.getProvider().getRuntime());
Here the API requires that the Ruby runtime object is passed to
RubyHash constructor.
Is this code thread-safe?
Can RubyHash objects be instantiated in another way?
I’m working with an existing Ruby code base that uses an opensource
Ruby module (Liquid) that doesn’t work with data structures created in
Java code. The only workaround I’ve come up with is to convert the
Java data structures to Ruby structures before passing them on to Ruby
code.
So, if I’m sharing a single (concurrent) ScriptingContainer between
multiple threads the following piece of code doesn’t expose the Ruby
runtime to race conditions if the Ruby code itself is thread safe?
RubyHash rh = new RubyHash(sc.getProvider().getRuntime());
The constructor call feels a bit verbose. Would it be possible to get
an overloaded constructor that would accept a ScriptingContainer
argument?
When you choose LocalContextScope.CONCURRENT model, thread-safety
depends on the Ruby code. If you want to make a Hash object
thread-safe, you should use java.util.concurrent.ConcuurentHashMap.
Java’s map type object behaves like Ruby’s Hash in Ruby code. For
example,
ScriptingContainer sc = new
ScriptingContainer(LocalContextScope.CONCURRENT);
ConcurrentHashMap myHash = new ConcurrentHashMap();
sc.put(“my_hash”, myHash);
on Java side. Then, my_hash is available to use on Ruby side. See my
blog post:
“4. New Map proxy” of
The change on Java’s Maps on Ruby side is done on Java side at the
same time. If you add some new key-value pairs in Ruby code, you can
see those pairs when you are back to Java code. This is because the
reference to the Map object is given to Ruby code.
-Yoko
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.