There is an alternative to removing Ruby, but I don't think it's very
attractive to us. However here it is for your information ...
We could run every Ruby API call from a single thread. We would start
a background thread (when exactly to do this is complex - more below).
The background thread would be the only one that uses RUBY_INIT_STACK.
nbdkit would make plugin requests through its threads, and these would
be enqueued and processed serially by the background thread. eg. The
.pread method would enqueue a 'RUBY_READ' message which the background
thread would pick up and process by calling into the Ruby plugin using
Ruby APIs. The result would be sent back to the nbdkit thread which
was doing the .pread, which would return the result.
(We use a similar technique for different reasons in VDDK and curl
plugins.)
Since all Ruby APIs are called on a single thread, presumably the Ruby
GC would only ever run on this same thread, and the stack problem
would not occur (even though this is not the nbdkit main thread).
I've not actually tested this, but it seems a reasonable assumption.
We would probably want to create the background thread early, not
least because plugins usually want to handle .config and other early
methods. But if we create the background thread in .load, then it
would be deleted when we fork (which is the purpose of the .after_fork
method - to create background threads after nbdkit has forked).
If we create the background thread in .after_fork, then it cannot
handle .config etc, unless those were queued up, but then error
handling is difficult.
Creating a background thread + Ruby interpreter in .load and then
creating a second background thread + Ruby interpreter in .after_fork
would requiring copying interpreter state from one thread to another
somehow.
We could also ban forking when using the Ruby plugin, but that
disables some important features such as '--run'.
As you can see, when you get into the details this is not a very
attractive option. Therefore I think deleting the Ruby plugin is the
best plan of action for us.
If people really want to write nbdkit plugins in Ruby, my suggestion
would be to use nbdkit-sh-plugin, and perhaps some sort of
"FastCGI"-type mechanism to ensure that the Ruby interpreter is
running in a separate process entirely from nbdkit.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html