grpc 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +39 -41
- data/bin/interop/interop_client.rb +1 -3
- data/bin/interop/interop_server.rb +2 -5
- data/ext/grpc/rb_byte_buffer.c +3 -4
- data/lib/grpc/generic/active_call.rb +4 -8
- data/lib/grpc/generic/bidi_call.rb +38 -34
- data/lib/grpc/generic/rpc_desc.rb +0 -1
- data/lib/grpc/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afd38727276d84cb2b01390533f09692b589e4d1
|
4
|
+
data.tar.gz: f078ad52dabd03355354f6ff78b58219462ca35f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 026fa39524d37611c0ed74ce7f3167a2ad66a617ada90b1fa4e22d56c803a352ede5e3f0264a6b46f8c8c64de52c026f45fa63177a30cab5ea877b070612b18b
|
7
|
+
data.tar.gz: fda00623627a68c253f10e8d61404ecdb4760ac46a57796b684336456bbc015c74ceb7dad82e62ba289c7810a91409bf882ab5c02e87797f70badad3d7d0ae2f
|
data/README.md
CHANGED
@@ -4,44 +4,48 @@ gRPC Ruby
|
|
4
4
|
A Ruby implementation of gRPC.
|
5
5
|
|
6
6
|
Status
|
7
|
-
|
7
|
+
-------
|
8
8
|
|
9
9
|
Alpha : Ready for early adopters
|
10
10
|
|
11
|
-
PREREQUISITES
|
12
|
-
|
11
|
+
INSTALLATION PREREQUISITES
|
12
|
+
--------------------------
|
13
13
|
|
14
|
-
|
15
|
-
- [homebrew][] on Mac OS X, [linuxbrew][] on Linux. These simplify the installation of the gRPC C core.
|
14
|
+
This requires Ruby 2.1, as the RPC API surface uses keyword args.
|
16
15
|
|
17
|
-
|
16
|
+
|
17
|
+
QUICK - INSTALL
|
18
18
|
---------------
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
- Clone this repository.
|
21
|
+
- Follow the instructions in [INSTALL](../../INSTALL) to install the gRPC C core.
|
22
|
+
- If you don't have Ruby 2.1 installed, switch to the more detailed instructions below
|
23
|
+
- Use bundler to install
|
21
24
|
```sh
|
22
|
-
$
|
25
|
+
$ # from this directory
|
26
|
+
$ gem install bundler && bundle install
|
23
27
|
```
|
24
|
-
This will download and run the [gRPC install script][], then install the latest version of gRPC Ruby gem. It also installs Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for ruby.
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
Installing from source
|
30
|
+
----------------------
|
31
|
+
|
29
32
|
- Build the gRPC C core
|
30
|
-
E.g, from the root of the gRPC [
|
33
|
+
E.g, from the root of the gRPC [git repo](https://github.com/google/grpc)
|
31
34
|
```sh
|
32
35
|
$ cd ../..
|
33
36
|
$ make && sudo make install
|
34
37
|
```
|
35
38
|
|
36
|
-
- Install Ruby 2.
|
39
|
+
- Install Ruby 2.1. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
|
37
40
|
the exact ruby version that's used.
|
38
41
|
```sh
|
39
42
|
$ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
|
40
|
-
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
|
43
|
+
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2.1
|
41
44
|
$
|
42
45
|
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
|
43
46
|
$ # and that the rvm command is installed
|
44
47
|
```
|
48
|
+
|
45
49
|
- Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set up of RVM
|
46
50
|
|
47
51
|
- Install [bundler](http://bundler.io/)
|
@@ -49,36 +53,30 @@ $ # and that the rvm command is installed
|
|
49
53
|
$ gem install bundler
|
50
54
|
```
|
51
55
|
|
52
|
-
- Finally,
|
56
|
+
- Finally, install the gRPC gem locally.
|
53
57
|
```sh
|
54
58
|
$ # from this directory
|
55
59
|
$ bundle install # creates the ruby bundle, including building the grpc extension
|
56
60
|
$ rake # runs the unit tests, see rake -T for other options
|
57
61
|
```
|
58
62
|
|
59
|
-
DOCUMENTATION
|
60
|
-
-------------
|
61
|
-
- rubydoc for the gRPC gem is available online at [rubydoc][].
|
62
|
-
- the gRPC Ruby reference documentation is available online at [grpc.io][]
|
63
|
-
|
64
63
|
CONTENTS
|
65
64
|
--------
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
[grpc.io]: http://www.grpc.io/docs/installation/ruby.html
|
65
|
+
|
66
|
+
Directory structure is the layout for [ruby extensions](http://guides.rubygems.org/gems-with-extensions/)
|
67
|
+
|
68
|
+
- ext:
|
69
|
+
the gRPC ruby extension
|
70
|
+
- lib:
|
71
|
+
the entrypoint gRPC ruby library to be used in a 'require' statement
|
72
|
+
- spec:
|
73
|
+
Rspec unittest
|
74
|
+
- bin:
|
75
|
+
example gRPC clients and servers, e.g,
|
76
|
+
```ruby
|
77
|
+
stub = Math::Math::Stub.new('my.test.math.server.com:8080')
|
78
|
+
req = Math::DivArgs.new(dividend: 7, divisor: 3)
|
79
|
+
logger.info("div(7/3): req=#{req.inspect}")
|
80
|
+
resp = stub.div(req)
|
81
|
+
logger.info("Answer: #{resp.inspect}")
|
82
|
+
```
|
@@ -274,7 +274,6 @@ class NamedTests
|
|
274
274
|
op = @stub.streaming_input_call(reqs, return_op: true)
|
275
275
|
op.cancel
|
276
276
|
assert_raises(GRPC::Cancelled) { op.execute }
|
277
|
-
assert(op.cancelled, 'call operation should be CANCELLED')
|
278
277
|
p 'OK: cancel_after_begin'
|
279
278
|
end
|
280
279
|
|
@@ -283,8 +282,7 @@ class NamedTests
|
|
283
282
|
ppp = PingPongPlayer.new(msg_sizes)
|
284
283
|
op = @stub.full_duplex_call(ppp.each_item, return_op: true)
|
285
284
|
ppp.canceller_op = op # causes ppp to cancel after the 1st message
|
286
|
-
op.execute.each { |r| ppp.queue.push(r) }
|
287
|
-
assert(op.cancelled, 'call operation should be CANCELLED')
|
285
|
+
assert_raises(GRPC::Cancelled) { op.execute.each { |r| ppp.queue.push(r) } }
|
288
286
|
p 'OK: cancel_after_first_response'
|
289
287
|
end
|
290
288
|
|
@@ -128,19 +128,16 @@ class TestTarget < Grpc::Testing::TestService::Service
|
|
128
128
|
cls = StreamingOutputCallResponse
|
129
129
|
Thread.new do
|
130
130
|
begin
|
131
|
-
GRPC.logger.info('interop-server: started receiving')
|
132
131
|
reqs.each do |req|
|
132
|
+
GRPC.logger.info("read #{req.inspect}")
|
133
133
|
resp_size = req.response_parameters[0].size
|
134
|
-
GRPC.logger.info("read a req, response size is #{resp_size}")
|
135
134
|
resp = cls.new(payload: Payload.new(type: req.response_type,
|
136
135
|
body: nulls(resp_size)))
|
137
136
|
q.push(resp)
|
138
137
|
end
|
139
|
-
GRPC.logger.info('
|
138
|
+
GRPC.logger.info('finished reads')
|
140
139
|
q.push(self)
|
141
140
|
rescue StandardError => e
|
142
|
-
GRPC.logger.info('interop-server: failed')
|
143
|
-
GRPC.logger.warn(e)
|
144
141
|
q.push(e) # share the exception with the enumerator
|
145
142
|
end
|
146
143
|
end
|
data/ext/grpc/rb_byte_buffer.c
CHANGED
@@ -36,7 +36,6 @@
|
|
36
36
|
#include <ruby/ruby.h>
|
37
37
|
|
38
38
|
#include <grpc/grpc.h>
|
39
|
-
#include <grpc/byte_buffer_reader.h>
|
40
39
|
#include <grpc/support/slice.h>
|
41
40
|
#include "rb_grpc.h"
|
42
41
|
|
@@ -51,7 +50,7 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
|
|
51
50
|
size_t length = 0;
|
52
51
|
char *string = NULL;
|
53
52
|
size_t offset = 0;
|
54
|
-
grpc_byte_buffer_reader reader;
|
53
|
+
grpc_byte_buffer_reader *reader = NULL;
|
55
54
|
gpr_slice next;
|
56
55
|
if (buffer == NULL) {
|
57
56
|
return Qnil;
|
@@ -59,8 +58,8 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
|
|
59
58
|
}
|
60
59
|
length = grpc_byte_buffer_length(buffer);
|
61
60
|
string = xmalloc(length + 1);
|
62
|
-
|
63
|
-
while (grpc_byte_buffer_reader_next(
|
61
|
+
reader = grpc_byte_buffer_reader_create(buffer);
|
62
|
+
while (grpc_byte_buffer_reader_next(reader, &next) != 0) {
|
64
63
|
memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
|
65
64
|
offset += GPR_SLICE_LENGTH(next);
|
66
65
|
}
|
@@ -39,7 +39,6 @@ class Struct
|
|
39
39
|
return nil if status.nil?
|
40
40
|
fail GRPC::Cancelled if status.code == GRPC::Core::StatusCodes::CANCELLED
|
41
41
|
if status.code != GRPC::Core::StatusCodes::OK
|
42
|
-
GRPC.logger.debug("Failing with status #{status}")
|
43
42
|
# raise BadStatus, propagating the metadata if present.
|
44
43
|
md = status.metadata
|
45
44
|
with_sym_keys = Hash[md.each_pair.collect { |x, y| [x.to_sym, y] }]
|
@@ -55,6 +54,7 @@ module GRPC
|
|
55
54
|
# The ActiveCall class provides simple methods for sending marshallable
|
56
55
|
# data to a call
|
57
56
|
class ActiveCall
|
57
|
+
include Core::StatusCodes
|
58
58
|
include Core::TimeConsts
|
59
59
|
include Core::CallOps
|
60
60
|
extend Forwardable
|
@@ -128,11 +128,6 @@ module GRPC
|
|
128
128
|
@output_metadata ||= {}
|
129
129
|
end
|
130
130
|
|
131
|
-
# cancelled indicates if the call was cancelled
|
132
|
-
def cancelled
|
133
|
-
!@call.status.nil? && @call.status.code == Core::StatusCodes::CANCELLED
|
134
|
-
end
|
135
|
-
|
136
131
|
# multi_req_view provides a restricted view of this ActiveCall for use
|
137
132
|
# in a server client-streaming handler.
|
138
133
|
def multi_req_view
|
@@ -166,7 +161,6 @@ module GRPC
|
|
166
161
|
ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished
|
167
162
|
batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
|
168
163
|
return unless assert_finished
|
169
|
-
@call.status = batch_result.status
|
170
164
|
batch_result.check_status
|
171
165
|
end
|
172
166
|
|
@@ -183,7 +177,6 @@ module GRPC
|
|
183
177
|
@call.metadata.merge!(batch_result.status.metadata)
|
184
178
|
end
|
185
179
|
end
|
186
|
-
@call.status = batch_result.status
|
187
180
|
batch_result.check_status
|
188
181
|
end
|
189
182
|
|
@@ -416,6 +409,9 @@ module GRPC
|
|
416
409
|
start_call(**kw) unless @started
|
417
410
|
bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline)
|
418
411
|
bd.run_on_client(requests, &blk)
|
412
|
+
rescue GRPC::Core::CallError => e
|
413
|
+
finished # checks for Cancelled
|
414
|
+
raise e
|
419
415
|
end
|
420
416
|
|
421
417
|
# run_server_bidi orchestrates a BiDi stream processing on a server.
|
@@ -78,9 +78,11 @@ module GRPC
|
|
78
78
|
# @param requests the Enumerable of requests to send
|
79
79
|
# @return an Enumerator of requests to yield
|
80
80
|
def run_on_client(requests, &blk)
|
81
|
-
@enq_th =
|
81
|
+
@enq_th = start_write_loop(requests)
|
82
82
|
@loop_th = start_read_loop
|
83
|
-
each_queued_msg
|
83
|
+
replies = each_queued_msg
|
84
|
+
return replies if blk.nil?
|
85
|
+
replies.each { |r| blk.call(r) }
|
84
86
|
end
|
85
87
|
|
86
88
|
# Begins orchestration of the Bidi stream for a server generating replies.
|
@@ -96,8 +98,8 @@ module GRPC
|
|
96
98
|
# @param gen_each_reply [Proc] generates the BiDi stream replies.
|
97
99
|
def run_on_server(gen_each_reply)
|
98
100
|
replys = gen_each_reply.call(each_queued_msg)
|
101
|
+
@enq_th = start_write_loop(replys, is_client: false)
|
99
102
|
@loop_th = start_read_loop
|
100
|
-
write_loop(replys, is_client: false)
|
101
103
|
end
|
102
104
|
|
103
105
|
private
|
@@ -113,7 +115,7 @@ module GRPC
|
|
113
115
|
return enum_for(:each_queued_msg) unless block_given?
|
114
116
|
count = 0
|
115
117
|
loop do
|
116
|
-
GRPC.logger.debug("each_queued_msg:
|
118
|
+
GRPC.logger.debug("each_queued_msg: msg##{count}")
|
117
119
|
count += 1
|
118
120
|
req = @readq.pop
|
119
121
|
GRPC.logger.debug("each_queued_msg: req = #{req}")
|
@@ -121,68 +123,70 @@ module GRPC
|
|
121
123
|
break if req.equal?(END_OF_READS)
|
122
124
|
yield req
|
123
125
|
end
|
126
|
+
@enq_th.join if @enq_th.alive?
|
124
127
|
end
|
125
128
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
129
|
+
# during bidi-streaming, read the requests to send from a separate thread
|
130
|
+
# read so that read_loop does not block waiting for requests to read.
|
131
|
+
def start_write_loop(requests, is_client: true)
|
132
|
+
Thread.new do # TODO: run on a thread pool
|
133
|
+
write_tag = Object.new
|
134
|
+
begin
|
135
|
+
count = 0
|
136
|
+
requests.each do |req|
|
137
|
+
GRPC.logger.debug("bidi-write_loop: #{count}")
|
138
|
+
count += 1
|
139
|
+
payload = @marshal.call(req)
|
140
|
+
@call.run_batch(@cq, write_tag, INFINITE_FUTURE,
|
141
|
+
SEND_MESSAGE => payload)
|
142
|
+
end
|
143
|
+
if is_client
|
144
|
+
GRPC.logger.debug("bidi-write-loop: sent #{count}, waiting")
|
145
|
+
batch_result = @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
|
146
|
+
SEND_CLOSE_FROM_CLIENT => nil,
|
147
|
+
RECV_STATUS_ON_CLIENT => nil)
|
148
|
+
batch_result.check_status
|
149
|
+
end
|
150
|
+
rescue StandardError => e
|
151
|
+
GRPC.logger.warn('bidi-write_loop: failed')
|
152
|
+
GRPC.logger.warn(e)
|
153
|
+
raise e
|
154
|
+
end
|
146
155
|
end
|
147
|
-
GRPC.logger.debug('bidi-write-loop: finished')
|
148
|
-
rescue StandardError => e
|
149
|
-
GRPC.logger.warn('bidi-write-loop: failed')
|
150
|
-
GRPC.logger.warn(e)
|
151
|
-
raise e
|
152
156
|
end
|
153
157
|
|
154
158
|
# starts the read loop
|
155
159
|
def start_read_loop
|
156
160
|
Thread.new do
|
157
|
-
GRPC.logger.debug('bidi-read-loop: starting')
|
158
161
|
begin
|
159
162
|
read_tag = Object.new
|
160
163
|
count = 0
|
164
|
+
|
161
165
|
# queue the initial read before beginning the loop
|
162
166
|
loop do
|
163
|
-
GRPC.logger.debug("bidi-
|
167
|
+
GRPC.logger.debug("bidi-read_loop: #{count}")
|
164
168
|
count += 1
|
165
169
|
# TODO: ensure metadata is read if available, currently it's not
|
166
170
|
batch_result = @call.run_batch(@cq, read_tag, INFINITE_FUTURE,
|
167
171
|
RECV_MESSAGE => nil)
|
168
172
|
# handle the next message
|
169
173
|
if batch_result.message.nil?
|
170
|
-
GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
|
171
174
|
@readq.push(END_OF_READS)
|
172
175
|
GRPC.logger.debug('bidi-read-loop: done reading!')
|
173
176
|
break
|
174
177
|
end
|
175
178
|
|
176
179
|
# push the latest read onto the queue and continue reading
|
180
|
+
GRPC.logger.debug("received req: #{batch_result.message}")
|
177
181
|
res = @unmarshal.call(batch_result.message)
|
178
182
|
@readq.push(res)
|
179
183
|
end
|
184
|
+
|
180
185
|
rescue StandardError => e
|
181
|
-
GRPC.logger.warn('bidi:
|
186
|
+
GRPC.logger.warn('bidi: read_loop failed')
|
182
187
|
GRPC.logger.warn(e)
|
183
188
|
@readq.push(e) # let each_queued_msg terminate with this error
|
184
189
|
end
|
185
|
-
GRPC.logger.debug('bidi-read-loop: finished')
|
186
190
|
end
|
187
191
|
end
|
188
192
|
end
|
@@ -137,7 +137,6 @@ module GRPC
|
|
137
137
|
|
138
138
|
def send_status(active_client, code, details, **kw)
|
139
139
|
details = 'Not sure why' if details.nil?
|
140
|
-
GRPC.logger.debug("Sending status #{code}:#{details}")
|
141
140
|
active_client.send_status(code, details, code == OK, **kw)
|
142
141
|
rescue StandardError => e
|
143
142
|
GRPC.logger.warn("Could not send status #{code}:#{details}")
|
data/lib/grpc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gRPC Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|