Skip to content

Commit

Permalink
Incorporating ruby into the master grpc repository.
Browse files Browse the repository at this point in the history
	Change on 2014/12/01 by nnoble <[email protected]>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=81111468
  • Loading branch information
nnoble committed Dec 2, 2014
1 parent 8ac074b commit 097ef9b
Show file tree
Hide file tree
Showing 64 changed files with 9,812 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/ruby/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
vendor
1 change: 1 addition & 0 deletions src/ruby/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-I.
13 changes: 13 additions & 0 deletions src/ruby/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
source 'https://rubygems.org'

# Modify this when working locally, see README.md
# e.g,
# gem 'beefcake', path: "/usr/local/google/repos/beefcake"
#
# The default value is what's used for gRPC ruby's GCE configuration
#
# gem 'beefcake', path: "/var/local/git/beefcake"
gem 'beefcake', path: "/usr/local/google/repos/beefcake"

# Specify your gem's dependencies in grpc.gemspec
gemspec
93 changes: 93 additions & 0 deletions src/ruby/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Ruby for GRPC
=============

LAYOUT
------

Directory structure is the recommended layout for [ruby extensions](http://guides.rubygems.org/gems-with-extensions/)

* ext: the extension code
* lib: the entrypoint grpc ruby library to be used in a 'require' statement
* test: tests


DEPENDENCIES
------------


* Extension

The extension can be built and tested using
[rake](https://rubygems.org/gems/rake). However, the rake-extensiontask rule
is not supported on older versions of rubygems, and the necessary version of
rubygems is not available on the latest version of Goobuntu.

This is resolved by using [RVM](https://rvm.io/) instead; install a single-user
ruby environment, and develop on the latest stable version of ruby (2.1.2).


* Proto code generation

To build generate service stubs and skeletons, it's currently necessary to use
a patched version of a beefcake, a simple third-party proto2 library. This is
feature compatible with proto3 and will be replaced by official proto3 support
in protoc.

* Patched protoc

The patched version of beefcake in turn depends on a patched version of protoc.
This is an update of the latest open source release of protoc with some forward
looking proto3 patches.


INSTALLATION PREREQUISITES
--------------------------

Install the patched protoc

$ cd <git_repo_dir>
$ git clone sso://team/one-platform-grpc-team/protobuf
$ cd protobuf
$ ./configure --prefix=/usr
$ make
$ sudo make install

Install RVM

$ \curl -sSL https://get.rvm.io | bash -s stable --ruby
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
$
$ gem install bundler # install bundler, the standard ruby package manager

Install the patched beefcake, and update the Gemfile to reference

$ cd <git_repo_dir>
$ git clone sso://team/one-platform-grpc-team/grpc-ruby-beefcake beefcake
$ cd beefcake
$ bundle install
$

HACKING
-------

The extension can be built and tested using the Rakefile.

$ # create a workspace
$ git5 start <your-git5-branch> net/grpc
$
$ # build the C library and install it in $HOME/grpc_dev
$ <google3>/net/grpc/c/build_gyp/build_grpc_dev.sh
$
$ # build the ruby extension and test it.
$ cd google3_dir/net/grpc/ruby
$ rake

Finally, install grpc ruby locally.

$ cd <this_dir>
$
$ # update the Gemfile, modify the line beginning # gem 'beefcake' to refer to
$ # the patched beefcake dir
$
$ bundle install

38 changes: 38 additions & 0 deletions src/ruby/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- ruby -*-
require 'rake/extensiontask'
require 'rspec/core/rake_task'


Rake::ExtensionTask.new 'grpc' do |ext|
ext.lib_dir = File.join('lib', 'grpc')
end

SPEC_SUITES = [
{ :id => :wrapper, :title => 'wrapper layer', :files => %w(spec/*.rb) },
{ :id => :idiomatic, :title => 'idiomatic layer', :dir => %w(spec/generic) }
]

desc "Run all RSpec tests"
namespace :spec do
namespace :suite do
SPEC_SUITES.each do |suite|
desc "Run all specs in #{suite[:title]} spec suite"
RSpec::Core::RakeTask.new(suite[:id]) do |t|
spec_files = []
if suite[:files]
suite[:files].each { |f| spec_files += Dir[f] }
end

if suite[:dirs]
suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
end

t.pattern = spec_files
end
end
end
end

desc "Run tests"
task :default => [ "spec:suite:wrapper", "spec:suite:idiomatic"]
task :spec => :compile
65 changes: 65 additions & 0 deletions src/ruby/bin/math.pb.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## Generated from bin/math.proto for math
require "beefcake"
require "grpc"

module Math

class DivArgs
include Beefcake::Message
end

class DivReply
include Beefcake::Message
end

class FibArgs
include Beefcake::Message
end

class Num
include Beefcake::Message
end

class FibReply
include Beefcake::Message
end

class DivArgs
required :dividend, :int64, 1
required :divisor, :int64, 2
end

class DivReply
required :quotient, :int64, 1
required :remainder, :int64, 2
end

class FibArgs
optional :limit, :int64, 1
end

class Num
required :num, :int64, 1
end

class FibReply
required :count, :int64, 1
end

module Math

class Service
include GRPC::GenericService

self.marshal_instance_method = :encode
self.unmarshal_class_method = :decode

rpc :Div, DivArgs, DivReply
rpc :DivMany, stream(DivArgs), stream(DivReply)
rpc :Fib, FibArgs, stream(Num)
rpc :Sum, stream(Num), Num
end
Stub = Service.rpc_stub_class

end
end
50 changes: 50 additions & 0 deletions src/ruby/bin/math.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
syntax = "proto2";

package math;

message DivArgs {
required int64 dividend = 1;
required int64 divisor = 2;
}

message DivReply {
required int64 quotient = 1;
required int64 remainder = 2;
}

message FibArgs {
optional int64 limit = 1;
}

message Num {
required int64 num = 1;
}

message FibReply {
required int64 count = 1;
}

service Math {
// Div divides args.dividend by args.divisor and returns the quotient and
// remainder.
rpc Div (DivArgs) returns (DivReply) {
}

// DivMany accepts an arbitrary number of division args from the client stream
// and sends back the results in the reply stream. The stream continues until
// the client closes its end; the server does the same after sending all the
// replies. The stream ends immediately if either end aborts.
rpc DivMany (stream DivArgs) returns (stream DivReply) {
}

// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib
// generates up to limit numbers; otherwise it continues until the call is
// canceled. Unlike Fib above, Fib has no final FibReply.
rpc Fib (FibArgs) returns (stream Num) {
}

// Sum sums a stream of numbers, returning the final result once the stream
// is closed.
rpc Sum (stream Num) returns (Num) {
}
}
110 changes: 110 additions & 0 deletions src/ruby/bin/math_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright 2014, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#!/usr/bin/env ruby
#
# Sample app that accesses a Calc service running on a Ruby gRPC server and
# helps validate RpcServer as a gRPC server using proto2 serialization.
#
# Usage: $ path/to/math_client.rb

this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(File.dirname(this_dir), 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)

require 'grpc'
require 'grpc/generic/client_stub'
require 'grpc/generic/service'
require 'math.pb'

def do_div(stub)
logger.info('request_response')
logger.info('----------------')
req = Math::DivArgs.new(:dividend => 7, :divisor => 3)
logger.info("div(7/3): req=#{req.inspect}")
resp = stub.div(req, deadline=GRPC::TimeConsts::INFINITE_FUTURE)
logger.info("Answer: #{resp.inspect}")
logger.info('----------------')
end

def do_sum(stub)
# to make client streaming requests, pass an enumerable of the inputs
logger.info('client_streamer')
logger.info('---------------')
reqs = [1, 2, 3, 4, 5].map { |x| Math::Num.new(:num => x) }
logger.info("sum(1, 2, 3, 4, 5): reqs=#{reqs.inspect}")
resp = stub.sum(reqs) # reqs.is_a?(Enumerable)
logger.info("Answer: #{resp.inspect}")
logger.info('---------------')
end

def do_fib(stub)
logger.info('server_streamer')
logger.info('----------------')
req = Math::FibArgs.new(:limit => 11)
logger.info("fib(11): req=#{req.inspect}")
resp = stub.fib(req, deadline=GRPC::TimeConsts::INFINITE_FUTURE)
resp.each do |r|
logger.info("Answer: #{r.inspect}")
end
logger.info('----------------')
end

def do_div_many(stub)
logger.info('bidi_streamer')
logger.info('-------------')
reqs = []
reqs << Math::DivArgs.new(:dividend => 7, :divisor => 3)
reqs << Math::DivArgs.new(:dividend => 5, :divisor => 2)
reqs << Math::DivArgs.new(:dividend => 7, :divisor => 2)
logger.info("div(7/3), div(5/2), div(7/2): reqs=#{reqs.inspect}")
resp = stub.div_many(reqs, deadline=10)
resp.each do |r|
logger.info("Answer: #{r.inspect}")
end
logger.info('----------------')
end


def main
host_port = 'localhost:7070'
if ARGV.size > 0
host_port = ARGV[0]
end
# The Math::Math:: module occurs because the service has the same name as its
# package. That practice should be avoided by defining real services.
stub = Math::Math::Stub.new(host_port)
do_div(stub)
do_sum(stub)
do_fib(stub)
do_div_many(stub)
end

main
Loading

0 comments on commit 097ef9b

Please sign in to comment.