From 2dbb479d5d3f89e6e4992299270f95c28da3b502 Mon Sep 17 00:00:00 2001 From: Jason Lunn Date: Tue, 14 Feb 2017 13:01:04 -0500 Subject: [PATCH 1/3] Create L4 to add JRuby support --- L4.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 L4.md diff --git a/L4.md b/L4.md new file mode 100644 index 000000000..dadf9ab2a --- /dev/null +++ b/L4.md @@ -0,0 +1,77 @@ +Title +---- +* Author(s): Jason Lunn +* Approver: a11r +* Status: Draft +* Implemented in: Ruby +* Last updated: 2017-02-14 +* Discussion at: https://github.com/grpc/grpc/issues/6705 + +## Abstract + +Add first class support for the JRuby interpreter by publishing a variant of the gem targeted to the `java` platform. + +## Background + +Dependency management for Ruby packages ("gems") relies on the availability of variant builds published to +[RubyGems.org](https://rubygems.org/) that declare what platform they target. Today, the `grpc` gem is already +supporting [five variants](https://rubygems.org/gems/grpc/versions) 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](https://github.com/grpc/grpc/issues/6705), the [JRuby](http://jruby.org/) 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](https://github.com/google/protobuf/blob/master/ruby/google-protobuf.gemspec#L12). + + +### Related Proposals: +* Not Applicable + +## Proposal + +1. Use [JBundler](https://github.com/mkristian/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. +1. Extend the existing [Gemspec](https://github.com/grpc/grpc/blob/master/grpc.gemspec) to add conditional logic that +both includes the JAR file and any necessary wrapper code and excludes C implementation files when run on JRuby. +1. Amend the standard gem release process to include publishing from the latest JRuby interpreter available at release +time. + +## Rationale + +#### Using a native library vs creating a "pure" Ruby client +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 questions of whether the performance would suffer too greatly if it were not +implemented in C and the maintenance burden of a completely standalone Ruby implementation are settled matters that were +already discussed when the Ruby client was first implemented. Therefore this proposal does not suggest creating a "pure" +Ruby implementation to address JRuby support. + +#### Creating a Maven dependency +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. + +## Implementation + +1. Update the Gemspec to add JBundler to the list of development dependencies when run on JRuby +1. Create a [JarFile](https://github.com/torquebox/maven-tools/wiki/Jarfile) to create a dependency on the grpc-java jar +1. Create wrapper code that delegates the existing Ruby API calls to the Java client, as needed +1. Address any test regressions or expectation updates introduced by executing on JRuby +1. Address any assumptions in documentation or code about the set of supported platforms, e.g. in the README for +[`grpc-tools`](https://github.com/grpc/grpc/blob/master/src/ruby/tools/README.md) +1. Update the release process tooling / and or documentation include JRuby specifics, as needed + +All points above except the last one can be community contributed. Project members would have to be responsible for the +last point as it is not exposed in the repository itself. + +## Open issues + +1. Is there a more correct heuristic for picking the version of the Maven artifact than keeping it unpinned so that it +selects the latest version available? From 3e01f466ac7667a752d29bc06c5a75ed59d82281 Mon Sep 17 00:00:00 2001 From: Jason Lunn Date: Wed, 15 Feb 2017 12:00:42 -0500 Subject: [PATCH 2/3] Changed review to apolcyn Updated discussion link to point at the newly created topic in the Google Group --- L4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L4.md b/L4.md index dadf9ab2a..c6497aab0 100644 --- a/L4.md +++ b/L4.md @@ -1,11 +1,11 @@ Title ---- * Author(s): Jason Lunn -* Approver: a11r +* Approver: apolcyn * Status: Draft * Implemented in: Ruby * Last updated: 2017-02-14 -* Discussion at: https://github.com/grpc/grpc/issues/6705 +* Discussion at: https://groups.google.com/forum/#!topic/grpc-io/4P6jg4ZYtfo ## Abstract From 62f456a311db0d8f2a9dae5931f7070fdc0a1f92 Mon Sep 17 00:00:00 2001 From: Jason Lunn Date: Tue, 6 Jun 2017 18:38:01 -0400 Subject: [PATCH 3/3] Updated with link to work in progress Additional details requested in the news group --- L4.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/L4.md b/L4.md index c6497aab0..5e96eaafd 100644 --- a/L4.md +++ b/L4.md @@ -4,7 +4,7 @@ Title * Approver: apolcyn * Status: Draft * Implemented in: Ruby -* Last updated: 2017-02-14 +* Last updated: 2017-06-06 * Discussion at: https://groups.google.com/forum/#!topic/grpc-io/4P6jg4ZYtfo ## Abstract @@ -36,7 +36,7 @@ Ruby client libraries maintained by Google, e.g. the Maven artifact published by the `gprc-java` project, exposing the JAR file to the Ruby build process when running on JRuby. 1. Extend the existing [Gemspec](https://github.com/grpc/grpc/blob/master/grpc.gemspec) to add conditional logic that -both includes the JAR file and any necessary wrapper code and excludes C implementation files when run on JRuby. +both includes the JAR file and any necessary wrapper code. It should also excludes C implementation files when run on JRuby. 1. Amend the standard gem release process to include publishing from the latest JRuby interpreter available at release time. @@ -44,10 +44,9 @@ time. #### Using a native library vs creating a "pure" Ruby client 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 questions of whether the performance would suffer too greatly if it were not -implemented in C and the maintenance burden of a completely standalone Ruby implementation are settled matters that were -already discussed when the Ruby client was first implemented. Therefore this proposal does not suggest creating a "pure" -Ruby implementation to address JRuby support. +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. #### Creating a Maven dependency The current organization of GRPC's source code repositories creates a challenge that other projects that support a Ruby @@ -60,18 +59,21 @@ no work required on their part to support this proposal. ## Implementation -1. Update the Gemspec to add JBundler to the list of development dependencies when run on JRuby -1. Create a [JarFile](https://github.com/torquebox/maven-tools/wiki/Jarfile) to create a dependency on the grpc-java jar +1. Update the Gemspec to add JBundler to the list of development dependencies when run on JRuby - :heavy_check_mark: +1. Create a [JarFile](https://github.com/torquebox/maven-tools/wiki/Jarfile) to create a dependency on the grpc-java jar - :heavy_check_mark: 1. Create wrapper code that delegates the existing Ruby API calls to the Java client, as needed -1. Address any test regressions or expectation updates introduced by executing on JRuby +1. Address any test regressions or expectation updates introduced by executing on JRuby - Current status: `145 examples, 22 failures` 1. Address any assumptions in documentation or code about the set of supported platforms, e.g. in the README for [`grpc-tools`](https://github.com/grpc/grpc/blob/master/src/ruby/tools/README.md) 1. Update the release process tooling / and or documentation include JRuby specifics, as needed -All points above except the last one can be community contributed. Project members would have to be responsible for the +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](https://github.com/JasonLunn/grpc/tree/l4_add_jruby_support). +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. ## Open issues -1. Is there a more correct heuristic for picking the version of the Maven artifact than keeping it unpinned so that it -selects the latest version available? +1. The remaining unit test failures are all in either `client_server_spec.rb` and `channel_connection_spec.rb` +1. How to add [interop testing](https://github.com/grpc/grpc-java/blob/master/interop-testing/build.gradle)