- Author(s): Jason Lunn [email protected]
- Approver: apolcyn
- Status: Draft
- Implemented in: Ruby
- Last updated: 2017-06-06
- Discussion at: https://groups.google.com/forum/#!topic/grpc-io/4P6jg4ZYtfo
Add first class support for the JRuby interpreter by publishing a variant of the gem targeted to the java
platform.
Dependency management for Ruby packages ("gems") relies on the availability of variant builds published to
RubyGems.org that declare what platform they target. Today, the grpc
gem is already
supporting five variants for every released version: x64-mingw32
,
x86_64-linux
, universal-darwin
, x86-mingw32
, in addition to a variant with no explicit platform.
As detailed in this issue, the JRuby interpreter (which is built on top of
the JVM) is not able to correctly resolve dependencies on the grpc
gem because it attempts and fails to build a native
extension that is implemented in C. While it possible on some versions of JRuby to make this approach work, it is much
more common (especially when a Java client library exists) to create a variant of the gem that declares as its target
the java
platform and expose a JAR-based implementation through a Ruby wrapper. This is the approach taken in other
Ruby client libraries maintained by Google, e.g.
Google Protobuf.
- Not Applicable
- Use JBundler or a comparable tool to facilitate expressing a dependency on
the Maven artifact published by the
gprc-java
project, exposing the JAR file to the Ruby build process when running on JRuby. - Extend the existing Gemspec to add conditional logic that both includes the JAR file and any necessary wrapper code. It should also excludes C implementation files when run on JRuby.
- Amend the standard gem release process to include publishing from the latest JRuby interpreter available at release time.
A "pure" Ruby client with no dependency on a native library would work equally well on JRuby as other Ruby interpreters. It is assumed that the question of whether performance would suffer too greatly if it were not implemented in C, as well as the maintenance burden of a completely standalone Ruby implementation are settled matters. Therefore this proposal does not suggest creating a "pure" Ruby implementation to address JRuby support.
The current organization of GRPC's source code repositories creates a challenge that other projects that support a Ruby
gem with dedicated support for clients running under JRuby do not have, namely that the Ruby source lives in a distinct
project from the source of the Java client. This proposal suggests using Maven to solve the artifact dependency in order
to avoid creating a requirement on a unified repository that includes the C, Ruby, and Java source in a single project.
That approach works fine (this is how Google Protobuf handles the same problem), and might even be more optimal, but
would require repository-level refactoring. The grpc-java
client already exposes releases via Maven so there would be
no work required on their part to support this proposal.
- Update the Gemspec to add JBundler to the list of development dependencies when run on JRuby - ✔️
- Create a JarFile to create a dependency on the grpc-java jar - ✔️
- Create wrapper code that delegates the existing Ruby API calls to the Java client, as needed
- Address any test regressions or expectation updates introduced by executing on JRuby - Current status:
145 examples, 22 failures
- Address any assumptions in documentation or code about the set of supported platforms, e.g. in the README for
grpc-tools
- Update the release process tooling / and or documentation include JRuby specifics, as needed
Points 1, 2 are feature complete, and partial implementations of points 3 and 4 can be found in a community contributed proof-of-concept branch.
All the outstanding test failures are in client_server_spec.rb
and channel_connection_spec.rb
- assistance from project members on how to leverage the Java API would be welcome.
All points above except the last one can be community contributed, though project members would be welcome to takeover in order to expedite. Project members would have to be responsible for the last point as it is not exposed in the repository itself.
- The remaining unit test failures are all in either
client_server_spec.rb
andchannel_connection_spec.rb
- How to add interop testing