Railgun is a Ruby client for a nailgun server. What is nailgun and why should you care?
Invoking Java command line utilities is costly. Most (and often, all) of the cost comes from spinning up a JVM for each invocation. nailgun (http://github.com/martylamb/nailgun) is a clever approach to resolve this issue. The idea is to keep a JVM running with all of the required classes loaded and use a thin client to execute arbitrary commands. Please see the nailgun project for more information.
While the C client that the nailgun project provides is great, it is still not easy to integrate it with existing Ruby applications. The goal of Railgun is to give developers a library that can be used to execute arbitrary code on the nailgun server and avoid invoking an external process or parsing the output from stdout or stderr of that process.
I hope this section gets smaller over time, but currently the following functionality (that is present in the C nailgun client is missing:
-
Interactive sessions Railgun essentially ignores the information from the server that it is ready to accept input and does not allow for an interactive usage.
-
Passing a file to the remote server (--nailgun-filearg) I think this is akin to doing something like:
awesome_command < foo
and allows for the file foo to be passed in. That is not currently implemented with Railgun.
The software is very much in the alpha stage and should be treated as such. The code is straightforward, but there may be bugs. To set it up:
-
Clone the github repository
-
Build the gem:
gem build railgun.gemspec
-
Install the gem
gem install railgun-0.0.1.gem
Lastly, the code does use Ruby 1.9 syntax and will not function on Ruby 1.8. Please use Ruby >= 1.9
Here is a short example of using Railgun. It assumes we have started the nailgun server with the com.example.HelloWorld class available and that class implements a main() method that will print out Hello World.
require 'railgun'
client = Railgun::Client.new
client.connect
result = client.execute('com.example.HelloWorld.Main')
client.close
puts result.out
puts result.err
puts result.exitcode
We can also supply arguments to the command. Imagine the main method accepts a string specifying the string to output. To do that, we can modify the code as follows:
require 'railgun'
client = Railgun::Client.new
client.connect
args = %w{ --string Goodbye }
result = client.execute('com.example.HelloWorld.Main', args: args)
client.close
puts result.out
puts result.err
puts result.exitcode
Lastly, the nailgun server expects 1 session per socket. That means you should instantiate a new Railgun::Client object for each new thread and avoid using a single Railgun::Client object across multiple threads.