grpc 0.9.4 → 0.10.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afd38727276d84cb2b01390533f09692b589e4d1
4
- data.tar.gz: f078ad52dabd03355354f6ff78b58219462ca35f
3
+ metadata.gz: 296a3415a75bad4a6d252472eea237cc77517ca0
4
+ data.tar.gz: facb8556323b3884eb64b8d9cf9332ee18502eed
5
5
  SHA512:
6
- metadata.gz: 026fa39524d37611c0ed74ce7f3167a2ad66a617ada90b1fa4e22d56c803a352ede5e3f0264a6b46f8c8c64de52c026f45fa63177a30cab5ea877b070612b18b
7
- data.tar.gz: fda00623627a68c253f10e8d61404ecdb4760ac46a57796b684336456bbc015c74ceb7dad82e62ba289c7810a91409bf882ab5c02e87797f70badad3d7d0ae2f
6
+ metadata.gz: 416c3b38ba0f659d6bf05fcc794a88fd7142a72f9b313229ffeb1d7f1adcf0d80ae78454ae38fc1e4d587f9ce430131f06d81d3dc7c028a7a69f800ab1ea8a1f
7
+ data.tar.gz: be7d80cafebe1a21aa9fa4f0f3fd1b19a447fffa641c2828f11de540e371157e39673b9841f07d9a1f251d41050160a6f3f7d181cceb09fd7e5ab77cb31d700d
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  -I.
2
2
  --require spec_helper
3
+ --format documentation
4
+ --color
@@ -12,7 +12,7 @@ Metrics/AbcSize:
12
12
  # Offense count: 3
13
13
  # Configuration parameters: CountComments.
14
14
  Metrics/ClassLength:
15
- Max: 192
15
+ Max: 200
16
16
 
17
17
  # Offense count: 35
18
18
  # Configuration parameters: CountComments.
data/README.md CHANGED
@@ -4,48 +4,44 @@ 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
- INSTALLATION PREREQUISITES
12
- --------------------------
11
+ PREREQUISITES
12
+ -------------
13
13
 
14
- This requires Ruby 2.1, as the RPC API surface uses keyword args.
14
+ - Ruby 2.x. The gRPC API uses keyword args.
15
+ - [homebrew][] on Mac OS X, [linuxbrew][] on Linux. These simplify the installation of the gRPC C core.
15
16
 
16
-
17
- QUICK - INSTALL
17
+ INSTALLATION
18
18
  ---------------
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
19
+ On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][].
20
+ Run the following command to install gRPC Ruby.
24
21
  ```sh
25
- $ # from this directory
26
- $ gem install bundler && bundle install
22
+ $ curl -fsSL https://goo.gl/getgrpc | bash -s ruby
27
23
  ```
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.
28
25
 
29
- Installing from source
30
- ----------------------
31
-
26
+ BUILD FROM SOURCE
27
+ ---------------------
28
+ - Clone this repository
32
29
  - Build the gRPC C core
33
- E.g, from the root of the gRPC [git repo](https://github.com/google/grpc)
30
+ E.g, from the root of the gRPC [Git repository](https://github.com/google/grpc)
34
31
  ```sh
35
32
  $ cd ../..
36
33
  $ make && sudo make install
37
34
  ```
38
35
 
39
- - Install Ruby 2.1. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
36
+ - Install Ruby 2.x. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
40
37
  the exact ruby version that's used.
41
38
  ```sh
42
39
  $ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
43
- $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2.1
40
+ $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
44
41
  $
45
42
  $ # follow the instructions to ensure that your're using the latest stable version of Ruby
46
43
  $ # and that the rvm command is installed
47
44
  ```
48
-
49
45
  - Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set up of RVM
50
46
 
51
47
  - Install [bundler](http://bundler.io/)
@@ -53,30 +49,36 @@ $ # and that the rvm command is installed
53
49
  $ gem install bundler
54
50
  ```
55
51
 
56
- - Finally, install the gRPC gem locally.
52
+ - Finally, build and install the gRPC gem locally.
57
53
  ```sh
58
54
  $ # from this directory
59
55
  $ bundle install # creates the ruby bundle, including building the grpc extension
60
56
  $ rake # runs the unit tests, see rake -T for other options
61
57
  ```
62
58
 
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
+
63
64
  CONTENTS
64
65
  --------
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
- ```
66
+ Directory structure is the layout for [ruby extensions][]
67
+ - ext: the gRPC ruby extension
68
+ - lib: the entrypoint gRPC ruby library to be used in a 'require' statement
69
+ - spec: Rspec unittests
70
+ - bin: example gRPC clients and servers, e.g,
71
+
72
+ ```ruby
73
+ stub = Math::Math::Stub.new('my.test.math.server.com:8080')
74
+ req = Math::DivArgs.new(dividend: 7, divisor: 3)
75
+ GRPC.logger.info("div(7/3): req=#{req.inspect}")
76
+ resp = stub.div(req)
77
+ GRPC.logger.info("Answer: #{resp.inspect}")
78
+ ```
79
+ [homebrew]:http://brew.sh
80
+ [linuxbrew]:https://github.com/Homebrew/linuxbrew#installation
81
+ [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
82
+ [ruby extensions]:http://guides.rubygems.org/gems-with-extensions/
83
+ [rubydoc]: http://www.rubydoc.info/gems/grpc
84
+ [grpc.io]: http://www.grpc.io/docs/installation/ruby.html
@@ -274,6 +274,7 @@ 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')
277
278
  p 'OK: cancel_after_begin'
278
279
  end
279
280
 
@@ -282,7 +283,9 @@ class NamedTests
282
283
  ppp = PingPongPlayer.new(msg_sizes)
283
284
  op = @stub.full_duplex_call(ppp.each_item, return_op: true)
284
285
  ppp.canceller_op = op # causes ppp to cancel after the 1st message
285
- assert_raises(GRPC::Cancelled) { op.execute.each { |r| ppp.queue.push(r) } }
286
+ op.execute.each { |r| ppp.queue.push(r) }
287
+ op.wait
288
+ assert(op.cancelled, 'call operation was not CANCELLED')
286
289
  p 'OK: cancel_after_first_response'
287
290
  end
288
291
 
@@ -128,16 +128,19 @@ 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')
131
132
  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}")
134
135
  resp = cls.new(payload: Payload.new(type: req.response_type,
135
136
  body: nulls(resp_size)))
136
137
  q.push(resp)
137
138
  end
138
- GRPC.logger.info('finished reads')
139
+ GRPC.logger.info('interop-server: finished receiving')
139
140
  q.push(self)
140
141
  rescue StandardError => e
142
+ GRPC.logger.info('interop-server: failed')
143
+ GRPC.logger.warn(e)
141
144
  q.push(e) # share the exception with the enumerator
142
145
  end
143
146
  end
@@ -54,44 +54,55 @@ LIB_DIRS = [
54
54
  LIBDIR
55
55
  ]
56
56
 
57
- # Check to see if GRPC_ROOT is defined or available
58
- grpc_root = ENV['GRPC_ROOT']
59
- if grpc_root.nil?
60
- r = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
61
- grpc_root = r if File.exist?(File.join(r, 'include/grpc/grpc.h'))
62
- end
63
-
64
- # When grpc_root is available attempt to build the grpc core.
65
- unless grpc_root.nil?
66
- grpc_config = ENV['GRPC_CONFIG'] || 'opt'
67
- if ENV.key?('GRPC_LIB_DIR')
68
- grpc_lib_dir = File.join(grpc_root, ENV['GRPC_LIB_DIR'])
69
- else
70
- grpc_lib_dir = File.join(File.join(grpc_root, 'libs'), grpc_config)
71
- end
72
- unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a'))
73
- system("make -C #{grpc_root} static_c CONFIG=#{grpc_config}")
57
+ def check_grpc_root
58
+ grpc_root = ENV['GRPC_ROOT']
59
+ if grpc_root.nil?
60
+ r = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
61
+ grpc_root = r if File.exist?(File.join(r, 'include/grpc/grpc.h'))
74
62
  end
75
- HEADER_DIRS.unshift File.join(grpc_root, 'include')
76
- LIB_DIRS.unshift grpc_lib_dir
63
+ grpc_root
77
64
  end
78
65
 
79
- def crash(msg)
80
- print(" extconf failure: #{msg}\n")
81
- exit 1
82
- end
66
+ grpc_pkg_config = system('pkg-config --exists grpc')
67
+
68
+ if grpc_pkg_config
69
+ $CFLAGS << ' ' + `pkg-config --static --cflags grpc`.strip + ' '
70
+ $LDFLAGS << ' ' + `pkg-config --static --libs grpc`.strip + ' '
71
+ else
72
+ dir_config('grpc', HEADER_DIRS, LIB_DIRS)
73
+ fail 'libdl not found' unless have_library('dl', 'dlopen')
74
+ fail 'zlib not found' unless have_library('z', 'inflate')
75
+ begin
76
+ fail 'Fail' unless have_library('gpr', 'gpr_now')
77
+ fail 'Fail' unless have_library('grpc', 'grpc_channel_destroy')
78
+ rescue
79
+ # Check to see if GRPC_ROOT is defined or available
80
+ grpc_root = check_grpc_root
83
81
 
84
- dir_config('grpc', HEADER_DIRS, LIB_DIRS)
82
+ # Stop if there is still no grpc_root
83
+ exit 1 if grpc_root.nil?
85
84
 
86
- $CFLAGS << ' -Wno-implicit-function-declaration '
87
- $CFLAGS << ' -Wno-pointer-sign '
88
- $CFLAGS << ' -Wno-return-type '
85
+ grpc_config = ENV['GRPC_CONFIG'] || 'opt'
86
+ if ENV.key?('GRPC_LIB_DIR')
87
+ grpc_lib_dir = File.join(grpc_root, ENV['GRPC_LIB_DIR'])
88
+ else
89
+ grpc_lib_dir = File.join(File.join(grpc_root, 'libs'), grpc_config)
90
+ end
91
+ unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a'))
92
+ print "Building internal gRPC\n"
93
+ system("make -C #{grpc_root} static_c CONFIG=#{grpc_config}")
94
+ end
95
+ $CFLAGS << ' -I' + File.join(grpc_root, 'include')
96
+ $LDFLAGS << ' -L' + grpc_lib_dir
97
+ raise 'gpr not found' unless have_library('gpr', 'gpr_now')
98
+ raise 'grpc not found' unless have_library('grpc', 'grpc_channel_destroy')
99
+ end
100
+ end
101
+
102
+ $CFLAGS << ' -std=c99 '
89
103
  $CFLAGS << ' -Wall '
104
+ $CFLAGS << ' -Wextra '
90
105
  $CFLAGS << ' -pedantic '
106
+ $CFLAGS << ' -Werror '
91
107
 
92
- $LDFLAGS << ' -lgrpc -lgpr -ldl'
93
-
94
- crash('need grpc lib') unless have_library('grpc', 'grpc_channel_destroy')
95
- have_library('grpc', 'grpc_channel_destroy')
96
- crash('need gpr lib') unless have_library('gpr', 'gpr_now')
97
108
  create_makefile('grpc/grpc')
@@ -36,12 +36,13 @@
36
36
  #include <ruby/ruby.h>
37
37
 
38
38
  #include <grpc/grpc.h>
39
+ #include <grpc/byte_buffer_reader.h>
39
40
  #include <grpc/support/slice.h>
40
41
  #include "rb_grpc.h"
41
42
 
42
43
  grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) {
43
44
  gpr_slice slice = gpr_slice_from_copied_buffer(string, length);
44
- grpc_byte_buffer *buffer = grpc_byte_buffer_create(&slice, 1);
45
+ grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1);
45
46
  gpr_slice_unref(slice);
46
47
  return buffer;
47
48
  }
@@ -50,7 +51,7 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
50
51
  size_t length = 0;
51
52
  char *string = NULL;
52
53
  size_t offset = 0;
53
- grpc_byte_buffer_reader *reader = NULL;
54
+ grpc_byte_buffer_reader reader;
54
55
  gpr_slice next;
55
56
  if (buffer == NULL) {
56
57
  return Qnil;
@@ -58,8 +59,8 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
58
59
  }
59
60
  length = grpc_byte_buffer_length(buffer);
60
61
  string = xmalloc(length + 1);
61
- reader = grpc_byte_buffer_reader_create(buffer);
62
- while (grpc_byte_buffer_reader_next(reader, &next) != 0) {
62
+ grpc_byte_buffer_reader_init(&reader, buffer);
63
+ while (grpc_byte_buffer_reader_next(&reader, &next) != 0) {
63
64
  memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
64
65
  offset += GPR_SLICE_LENGTH(next);
65
66
  }
@@ -507,6 +507,7 @@ static void grpc_run_batch_stack_fill_ops(run_batch_stack *st, VALUE ops_hash) {
507
507
  NUM2INT(this_op));
508
508
  };
509
509
  st->ops[st->op_num].op = (grpc_op_type)NUM2INT(this_op);
510
+ st->ops[st->op_num].flags = 0;
510
511
  st->op_num++;
511
512
  }
512
513
  }
@@ -142,8 +142,16 @@ grpc_event grpc_rb_completion_queue_pluck_event(VALUE self, VALUE tag,
142
142
  MEMZERO(&next_call, next_call_stack, 1);
143
143
  TypedData_Get_Struct(self, grpc_completion_queue,
144
144
  &grpc_rb_completion_queue_data_type, next_call.cq);
145
- next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
146
- next_call.tag = ROBJECT(tag);
145
+ if (TYPE(timeout) == T_NIL) {
146
+ next_call.timeout = gpr_inf_future;
147
+ } else {
148
+ next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
149
+ }
150
+ if (TYPE(tag) == T_NIL) {
151
+ next_call.tag = NULL;
152
+ } else {
153
+ next_call.tag = ROBJECT(tag);
154
+ }
147
155
  next_call.event.type = GRPC_QUEUE_TIMEOUT;
148
156
  rb_thread_call_without_gvl(grpc_rb_completion_queue_pluck_no_gil,
149
157
  (void *)&next_call, NULL, NULL);
@@ -68,8 +68,12 @@ static void grpc_rb_server_free(void *p) {
68
68
 
69
69
  /* Deletes the wrapped object if the mark object is Qnil, which indicates
70
70
  that no other object is the actual owner. */
71
+ /* grpc_server_shutdown does not exist. Change this to something that does
72
+ or delete it */
71
73
  if (svr->wrapped != NULL && svr->mark == Qnil) {
72
- grpc_server_shutdown(svr->wrapped);
74
+ // grpc_server_shutdown(svr->wrapped);
75
+ // Aborting to indicate a bug
76
+ abort();
73
77
  grpc_server_destroy(svr->wrapped);
74
78
  }
75
79
 
@@ -210,7 +214,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
210
214
  VALUE result;
211
215
  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
212
216
  if (s->wrapped == NULL) {
213
- rb_raise(rb_eRuntimeError, "closed!");
217
+ rb_raise(rb_eRuntimeError, "destroyed!");
214
218
  return Qnil;
215
219
  } else {
216
220
  grpc_request_call_stack_init(&st);
@@ -259,21 +263,69 @@ static VALUE grpc_rb_server_start(VALUE self) {
259
263
  grpc_rb_server *s = NULL;
260
264
  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
261
265
  if (s->wrapped == NULL) {
262
- rb_raise(rb_eRuntimeError, "closed!");
266
+ rb_raise(rb_eRuntimeError, "destroyed!");
263
267
  } else {
264
268
  grpc_server_start(s->wrapped);
265
269
  }
266
270
  return Qnil;
267
271
  }
268
272
 
269
- static VALUE grpc_rb_server_destroy(VALUE self) {
273
+ /*
274
+ call-seq:
275
+ cq = CompletionQueue.new
276
+ server = Server.new(cq, {'arg1': 'value1'})
277
+ ... // do stuff with server
278
+ ...
279
+ ... // to shutdown the server
280
+ server.destroy(cq)
281
+
282
+ ... // to shutdown the server with a timeout
283
+ server.destroy(cq, timeout)
284
+
285
+ Destroys server instances. */
286
+ static VALUE grpc_rb_server_destroy(int argc, VALUE *argv, VALUE self) {
287
+ VALUE cqueue = Qnil;
288
+ VALUE timeout = Qnil;
289
+ grpc_completion_queue *cq = NULL;
290
+ grpc_event ev;
270
291
  grpc_rb_server *s = NULL;
292
+
293
+ /* "11" == 1 mandatory args, 1 (timeout) is optional */
294
+ rb_scan_args(argc, argv, "11", &cqueue, &timeout);
295
+ cq = grpc_rb_get_wrapped_completion_queue(cqueue);
271
296
  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
297
+
272
298
  if (s->wrapped != NULL) {
273
- grpc_server_shutdown(s->wrapped);
299
+ grpc_server_shutdown_and_notify(s->wrapped, cq, NULL);
300
+ ev = grpc_rb_completion_queue_pluck_event(cqueue, Qnil, timeout);
301
+
302
+ if (!ev.success) {
303
+ rb_warn("server shutdown failed, there will be a LEAKED object warning");
304
+ return Qnil;
305
+ /*
306
+ TODO: renable the rb_raise below.
307
+
308
+ At the moment if the timeout is INFINITE_FUTURE as recommended, the
309
+ pluck blocks forever, even though
310
+
311
+ the outstanding server_request_calls correctly fail on the other
312
+ thread that they are running on.
313
+
314
+ it's almost as if calls that fail on the other thread do not get
315
+ cleaned up by shutdown request, even though it caused htem to
316
+ terminate.
317
+
318
+ rb_raise(rb_eRuntimeError, "grpc server shutdown did not succeed");
319
+ return Qnil;
320
+
321
+ The workaround is just to use a timeout and return without really
322
+ shutting down the server, and rely on the grpc core garbage collection
323
+ it down as a 'LEAKED OBJECT'.
324
+
325
+ */
326
+ }
274
327
  grpc_server_destroy(s->wrapped);
275
328
  s->wrapped = NULL;
276
- s->mark = Qnil;
277
329
  }
278
330
  return Qnil;
279
331
  }
@@ -302,7 +354,7 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
302
354
 
303
355
  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
304
356
  if (s->wrapped == NULL) {
305
- rb_raise(rb_eRuntimeError, "closed!");
357
+ rb_raise(rb_eRuntimeError, "destroyed!");
306
358
  return Qnil;
307
359
  } else if (rb_creds == Qnil) {
308
360
  recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port));
@@ -315,7 +367,7 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
315
367
  creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
316
368
  recvd_port =
317
369
  grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port),
318
- creds);
370
+ creds);
319
371
  if (recvd_port == 0) {
320
372
  rb_raise(rb_eRuntimeError,
321
373
  "could not add secure port %s to server, not sure why",
@@ -341,7 +393,7 @@ void Init_grpc_server() {
341
393
  rb_define_method(grpc_rb_cServer, "request_call",
342
394
  grpc_rb_server_request_call, 3);
343
395
  rb_define_method(grpc_rb_cServer, "start", grpc_rb_server_start, 0);
344
- rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, 0);
396
+ rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, -1);
345
397
  rb_define_alias(grpc_rb_cServer, "close", "destroy");
346
398
  rb_define_method(grpc_rb_cServer, "add_http2_port",
347
399
  grpc_rb_server_add_http2_port,
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.license = 'BSD-3-Clause'
15
15
 
16
16
  s.required_ruby_version = '>= 2.0.0'
17
- s.requirements << 'libgrpc ~> 0.9.1 needs to be installed'
17
+ s.requirements << 'libgrpc ~> 0.10.0 needs to be installed'
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- spec/*`.split("\n")
@@ -39,6 +39,7 @@ 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}")
42
43
  # raise BadStatus, propagating the metadata if present.
43
44
  md = status.metadata
44
45
  with_sym_keys = Hash[md.each_pair.collect { |x, y| [x.to_sym, y] }]
@@ -54,7 +55,6 @@ module GRPC
54
55
  # The ActiveCall class provides simple methods for sending marshallable
55
56
  # data to a call
56
57
  class ActiveCall
57
- include Core::StatusCodes
58
58
  include Core::TimeConsts
59
59
  include Core::CallOps
60
60
  extend Forwardable
@@ -120,6 +120,7 @@ module GRPC
120
120
  @started = started
121
121
  @unmarshal = unmarshal
122
122
  @metadata_tag = metadata_tag
123
+ @op_notifier = nil
123
124
  end
124
125
 
125
126
  # output_metadata are provides access to hash that can be used to
@@ -128,6 +129,11 @@ module GRPC
128
129
  @output_metadata ||= {}
129
130
  end
130
131
 
132
+ # cancelled indicates if the call was cancelled
133
+ def cancelled
134
+ !@call.status.nil? && @call.status.code == Core::StatusCodes::CANCELLED
135
+ end
136
+
131
137
  # multi_req_view provides a restricted view of this ActiveCall for use
132
138
  # in a server client-streaming handler.
133
139
  def multi_req_view
@@ -143,6 +149,7 @@ module GRPC
143
149
  # operation provides a restricted view of this ActiveCall for use as
144
150
  # a Operation.
145
151
  def operation
152
+ @op_notifier = Notifier.new
146
153
  Operation.new(self)
147
154
  end
148
155
 
@@ -161,6 +168,8 @@ module GRPC
161
168
  ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished
162
169
  batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
163
170
  return unless assert_finished
171
+ @call.status = batch_result.status
172
+ op_is_done
164
173
  batch_result.check_status
165
174
  end
166
175
 
@@ -177,6 +186,8 @@ module GRPC
177
186
  @call.metadata.merge!(batch_result.status.metadata)
178
187
  end
179
188
  end
189
+ @call.status = batch_result.status
190
+ op_is_done
180
191
  batch_result.check_status
181
192
  end
182
193
 
@@ -408,10 +419,7 @@ module GRPC
408
419
  def bidi_streamer(requests, **kw, &blk)
409
420
  start_call(**kw) unless @started
410
421
  bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline)
411
- bd.run_on_client(requests, &blk)
412
- rescue GRPC::Core::CallError => e
413
- finished # checks for Cancelled
414
- raise e
422
+ bd.run_on_client(requests, @op_notifier, &blk)
415
423
  end
416
424
 
417
425
  # run_server_bidi orchestrates a BiDi stream processing on a server.
@@ -430,6 +438,19 @@ module GRPC
430
438
  bd.run_on_server(gen_each_reply)
431
439
  end
432
440
 
441
+ # Waits till an operation completes
442
+ def wait
443
+ return if @op_notifier.nil?
444
+ GRPC.logger.debug("active_call.wait: on #{@op_notifier}")
445
+ @op_notifier.wait
446
+ end
447
+
448
+ # Signals that an operation is done
449
+ def op_is_done
450
+ return if @op_notifier.nil?
451
+ @op_notifier.notify(self)
452
+ end
453
+
433
454
  private
434
455
 
435
456
  # Starts the call if not already started
@@ -464,6 +485,6 @@ module GRPC
464
485
  # Operation limits access to an ActiveCall's methods for use as
465
486
  # a Operation on the client.
466
487
  Operation = view_class(:cancel, :cancelled, :deadline, :execute,
467
- :metadata, :status, :start_call)
488
+ :metadata, :status, :start_call, :wait)
468
489
  end
469
490
  end
@@ -66,6 +66,7 @@ module GRPC
66
66
  @cq = q
67
67
  @deadline = deadline
68
68
  @marshal = marshal
69
+ @op_notifier = nil # signals completion on clients
69
70
  @readq = Queue.new
70
71
  @unmarshal = unmarshal
71
72
  end
@@ -76,13 +77,13 @@ module GRPC
76
77
  # block that can be invoked with each response.
77
78
  #
78
79
  # @param requests the Enumerable of requests to send
80
+ # @op_notifier a Notifier used to signal completion
79
81
  # @return an Enumerator of requests to yield
80
- def run_on_client(requests, &blk)
81
- @enq_th = start_write_loop(requests)
82
+ def run_on_client(requests, op_notifier, &blk)
83
+ @op_notifier = op_notifier
84
+ @enq_th = Thread.new { write_loop(requests) }
82
85
  @loop_th = start_read_loop
83
- replies = each_queued_msg
84
- return replies if blk.nil?
85
- replies.each { |r| blk.call(r) }
86
+ each_queued_msg(&blk)
86
87
  end
87
88
 
88
89
  # Begins orchestration of the Bidi stream for a server generating replies.
@@ -98,8 +99,8 @@ module GRPC
98
99
  # @param gen_each_reply [Proc] generates the BiDi stream replies.
99
100
  def run_on_server(gen_each_reply)
100
101
  replys = gen_each_reply.call(each_queued_msg)
101
- @enq_th = start_write_loop(replys, is_client: false)
102
102
  @loop_th = start_read_loop
103
+ write_loop(replys, is_client: false)
103
104
  end
104
105
 
105
106
  private
@@ -107,6 +108,13 @@ module GRPC
107
108
  END_OF_READS = :end_of_reads
108
109
  END_OF_WRITES = :end_of_writes
109
110
 
111
+ # signals that bidi operation is complete
112
+ def notify_done
113
+ return unless @op_notifier
114
+ GRPC.logger.debug("bidi-notify-done: notifying #{@op_notifier}")
115
+ @op_notifier.notify(self)
116
+ end
117
+
110
118
  # each_queued_msg yields each message on this instances readq
111
119
  #
112
120
  # - messages are added to the readq by #read_loop
@@ -115,7 +123,7 @@ module GRPC
115
123
  return enum_for(:each_queued_msg) unless block_given?
116
124
  count = 0
117
125
  loop do
118
- GRPC.logger.debug("each_queued_msg: msg##{count}")
126
+ GRPC.logger.debug("each_queued_msg: waiting##{count}")
119
127
  count += 1
120
128
  req = @readq.pop
121
129
  GRPC.logger.debug("each_queued_msg: req = #{req}")
@@ -123,70 +131,70 @@ module GRPC
123
131
  break if req.equal?(END_OF_READS)
124
132
  yield req
125
133
  end
126
- @enq_th.join if @enq_th.alive?
127
134
  end
128
135
 
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
136
+ def write_loop(requests, is_client: true)
137
+ GRPC.logger.debug('bidi-write-loop: starting')
138
+ write_tag = Object.new
139
+ count = 0
140
+ requests.each do |req|
141
+ GRPC.logger.debug("bidi-write-loop: #{count}")
142
+ count += 1
143
+ payload = @marshal.call(req)
144
+ @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
145
+ SEND_MESSAGE => payload)
155
146
  end
147
+ GRPC.logger.debug("bidi-write-loop: #{count} writes done")
148
+ if is_client
149
+ GRPC.logger.debug("bidi-write-loop: client sent #{count}, waiting")
150
+ batch_result = @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
151
+ SEND_CLOSE_FROM_CLIENT => nil,
152
+ RECV_STATUS_ON_CLIENT => nil)
153
+ @call.status = batch_result.status
154
+ batch_result.check_status
155
+ GRPC.logger.debug("bidi-write-loop: done status #{@call.status}")
156
+ notify_done
157
+ end
158
+ GRPC.logger.debug('bidi-write-loop: finished')
159
+ rescue StandardError => e
160
+ GRPC.logger.warn('bidi-write-loop: failed')
161
+ GRPC.logger.warn(e)
162
+ notify_done
163
+ raise e
156
164
  end
157
165
 
158
166
  # starts the read loop
159
167
  def start_read_loop
160
168
  Thread.new do
169
+ GRPC.logger.debug('bidi-read-loop: starting')
161
170
  begin
162
171
  read_tag = Object.new
163
172
  count = 0
164
-
165
173
  # queue the initial read before beginning the loop
166
174
  loop do
167
- GRPC.logger.debug("bidi-read_loop: #{count}")
175
+ GRPC.logger.debug("bidi-read-loop: #{count}")
168
176
  count += 1
169
177
  # TODO: ensure metadata is read if available, currently it's not
170
178
  batch_result = @call.run_batch(@cq, read_tag, INFINITE_FUTURE,
171
179
  RECV_MESSAGE => nil)
172
180
  # handle the next message
173
181
  if batch_result.message.nil?
182
+ GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
174
183
  @readq.push(END_OF_READS)
175
184
  GRPC.logger.debug('bidi-read-loop: done reading!')
176
185
  break
177
186
  end
178
187
 
179
188
  # push the latest read onto the queue and continue reading
180
- GRPC.logger.debug("received req: #{batch_result.message}")
181
189
  res = @unmarshal.call(batch_result.message)
182
190
  @readq.push(res)
183
191
  end
184
-
185
192
  rescue StandardError => e
186
- GRPC.logger.warn('bidi: read_loop failed')
193
+ GRPC.logger.warn('bidi: read-loop failed')
187
194
  GRPC.logger.warn(e)
188
195
  @readq.push(e) # let each_queued_msg terminate with this error
189
196
  end
197
+ GRPC.logger.debug('bidi-read-loop: finished')
190
198
  end
191
199
  end
192
200
  end
@@ -137,6 +137,7 @@ 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}")
140
141
  active_client.send_status(code, details, code == OK, **kw)
141
142
  rescue StandardError => e
142
143
  GRPC.logger.warn("Could not send status #{code}:#{details}")
@@ -278,7 +278,9 @@ module GRPC
278
278
  @stopped = true
279
279
  end
280
280
  @pool.stop
281
- @server.close
281
+ deadline = from_relative_time(@poll_period)
282
+
283
+ @server.close(@cq, deadline)
282
284
  end
283
285
 
284
286
  # determines if the server has been stopped
@@ -410,17 +412,18 @@ module GRPC
410
412
  # handles calls to the server
411
413
  def loop_handle_server_calls
412
414
  fail 'not running' unless @running
413
- request_call_tag = Object.new
415
+ loop_tag = Object.new
414
416
  until stopped?
415
417
  deadline = from_relative_time(@poll_period)
416
418
  begin
417
- an_rpc = @server.request_call(@cq, request_call_tag, deadline)
419
+ an_rpc = @server.request_call(@cq, loop_tag, deadline)
420
+ c = new_active_server_call(an_rpc)
418
421
  rescue Core::CallError, RuntimeError => e
419
- # can happen during server shutdown
422
+ # these might happen for various reasonse. The correct behaviour of
423
+ # the server is to log them and continue.
420
424
  GRPC.logger.warn("server call failed: #{e}")
421
425
  next
422
426
  end
423
- c = new_active_server_call(an_rpc)
424
427
  unless c.nil?
425
428
  mth = an_rpc.method.to_sym
426
429
  @pool.schedule(c) do |call|
@@ -38,6 +38,6 @@ Logging.logger.root.appenders = Logging.appenders.stdout
38
38
  Logging.logger.root.level = :info
39
39
 
40
40
  # TODO: provide command-line configuration for logging
41
- Logging.logger['GRPC'].level = :debug
41
+ Logging.logger['GRPC'].level = :info
42
42
  Logging.logger['GRPC::ActiveCall'].level = :info
43
43
  Logging.logger['GRPC::BidiCall'].level = :info
@@ -29,5 +29,5 @@
29
29
 
30
30
  # GRPC contains the General RPC module.
31
31
  module GRPC
32
- VERSION = '0.9.4'
32
+ VERSION = '0.10.0'
33
33
  end
@@ -42,11 +42,8 @@ shared_context 'setup: tags' do
42
42
  let(:sent_message) { 'sent message' }
43
43
  let(:reply_text) { 'the reply' }
44
44
  before(:example) do
45
- @server_finished_tag = Object.new
46
- @client_finished_tag = Object.new
47
- @client_metadata_tag = Object.new
45
+ @client_tag = Object.new
48
46
  @server_tag = Object.new
49
- @tag = Object.new
50
47
  end
51
48
 
52
49
  def deadline
@@ -74,6 +71,12 @@ shared_examples 'basic GRPC message delivery is OK' do
74
71
 
75
72
  it 'servers receive requests from clients and can respond' do
76
73
  call = new_client_call
74
+ server_call = nil
75
+
76
+ server_thread = Thread.new do
77
+ server_call = server_allows_client_to_proceed
78
+ end
79
+
77
80
  client_ops = {
78
81
  CallOps::SEND_INITIAL_METADATA => {},
79
82
  CallOps::SEND_MESSAGE => sent_message
@@ -84,7 +87,7 @@ shared_examples 'basic GRPC message delivery is OK' do
84
87
  expect(batch_result.send_message).to be true
85
88
 
86
89
  # confirm the server can read the inbound message
87
- server_call = server_allows_client_to_proceed
90
+ server_thread.join
88
91
  server_ops = {
89
92
  CallOps::RECV_MESSAGE => nil
90
93
  }
@@ -95,6 +98,12 @@ shared_examples 'basic GRPC message delivery is OK' do
95
98
 
96
99
  it 'responses written by servers are received by the client' do
97
100
  call = new_client_call
101
+ server_call = nil
102
+
103
+ server_thread = Thread.new do
104
+ server_call = server_allows_client_to_proceed
105
+ end
106
+
98
107
  client_ops = {
99
108
  CallOps::SEND_INITIAL_METADATA => {},
100
109
  CallOps::SEND_MESSAGE => sent_message
@@ -105,7 +114,7 @@ shared_examples 'basic GRPC message delivery is OK' do
105
114
  expect(batch_result.send_message).to be true
106
115
 
107
116
  # confirm the server can read the inbound message
108
- server_call = server_allows_client_to_proceed
117
+ server_thread.join
109
118
  server_ops = {
110
119
  CallOps::RECV_MESSAGE => nil,
111
120
  CallOps::SEND_MESSAGE => reply_text
@@ -118,6 +127,12 @@ shared_examples 'basic GRPC message delivery is OK' do
118
127
 
119
128
  it 'servers can ignore a client write and send a status' do
120
129
  call = new_client_call
130
+ server_call = nil
131
+
132
+ server_thread = Thread.new do
133
+ server_call = server_allows_client_to_proceed
134
+ end
135
+
121
136
  client_ops = {
122
137
  CallOps::SEND_INITIAL_METADATA => {},
123
138
  CallOps::SEND_MESSAGE => sent_message
@@ -129,7 +144,7 @@ shared_examples 'basic GRPC message delivery is OK' do
129
144
 
130
145
  # confirm the server can read the inbound message
131
146
  the_status = Struct::Status.new(StatusCodes::OK, 'OK')
132
- server_call = server_allows_client_to_proceed
147
+ server_thread.join
133
148
  server_ops = {
134
149
  CallOps::SEND_STATUS_FROM_SERVER => the_status
135
150
  }
@@ -141,6 +156,12 @@ shared_examples 'basic GRPC message delivery is OK' do
141
156
 
142
157
  it 'completes calls by sending status to client and server' do
143
158
  call = new_client_call
159
+ server_call = nil
160
+
161
+ server_thread = Thread.new do
162
+ server_call = server_allows_client_to_proceed
163
+ end
164
+
144
165
  client_ops = {
145
166
  CallOps::SEND_INITIAL_METADATA => {},
146
167
  CallOps::SEND_MESSAGE => sent_message
@@ -152,7 +173,7 @@ shared_examples 'basic GRPC message delivery is OK' do
152
173
 
153
174
  # confirm the server can read the inbound message and respond
154
175
  the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
155
- server_call = server_allows_client_to_proceed
176
+ server_thread.join
156
177
  server_ops = {
157
178
  CallOps::RECV_MESSAGE => nil,
158
179
  CallOps::SEND_MESSAGE => reply_text,
@@ -221,6 +242,11 @@ shared_examples 'GRPC metadata delivery works OK' do
221
242
 
222
243
  it 'sends all the metadata pairs when keys and values are valid' do
223
244
  @valid_metadata.each do |md|
245
+ recvd_rpc = nil
246
+ rcv_thread = Thread.new do
247
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
248
+ end
249
+
224
250
  call = new_client_call
225
251
  client_ops = {
226
252
  CallOps::SEND_INITIAL_METADATA => md
@@ -230,7 +256,7 @@ shared_examples 'GRPC metadata delivery works OK' do
230
256
  expect(batch_result.send_metadata).to be true
231
257
 
232
258
  # confirm the server can receive the client metadata
233
- recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
259
+ rcv_thread.join
234
260
  expect(recvd_rpc).to_not eq nil
235
261
  recvd_md = recvd_rpc.metadata
236
262
  replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
@@ -257,6 +283,11 @@ shared_examples 'GRPC metadata delivery works OK' do
257
283
 
258
284
  it 'raises an exception if a metadata key is invalid' do
259
285
  @bad_keys.each do |md|
286
+ recvd_rpc = nil
287
+ rcv_thread = Thread.new do
288
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
289
+ end
290
+
260
291
  call = new_client_call
261
292
  # client signals that it's done sending metadata to allow server to
262
293
  # respond
@@ -266,7 +297,7 @@ shared_examples 'GRPC metadata delivery works OK' do
266
297
  call.run_batch(@client_queue, @client_tag, deadline, client_ops)
267
298
 
268
299
  # server gets the invocation
269
- recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
300
+ rcv_thread.join
270
301
  expect(recvd_rpc).to_not eq nil
271
302
  server_ops = {
272
303
  CallOps::SEND_INITIAL_METADATA => md
@@ -280,6 +311,11 @@ shared_examples 'GRPC metadata delivery works OK' do
280
311
  end
281
312
 
282
313
  it 'sends an empty hash if no metadata is added' do
314
+ recvd_rpc = nil
315
+ rcv_thread = Thread.new do
316
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
317
+ end
318
+
283
319
  call = new_client_call
284
320
  # client signals that it's done sending metadata to allow server to
285
321
  # respond
@@ -289,7 +325,7 @@ shared_examples 'GRPC metadata delivery works OK' do
289
325
  call.run_batch(@client_queue, @client_tag, deadline, client_ops)
290
326
 
291
327
  # server gets the invocation but sends no metadata back
292
- recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
328
+ rcv_thread.join
293
329
  expect(recvd_rpc).to_not eq nil
294
330
  server_call = recvd_rpc.call
295
331
  server_ops = {
@@ -308,6 +344,11 @@ shared_examples 'GRPC metadata delivery works OK' do
308
344
 
309
345
  it 'sends all the pairs when keys and values are valid' do
310
346
  @valid_metadata.each do |md|
347
+ recvd_rpc = nil
348
+ rcv_thread = Thread.new do
349
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
350
+ end
351
+
311
352
  call = new_client_call
312
353
  # client signals that it's done sending metadata to allow server to
313
354
  # respond
@@ -317,7 +358,7 @@ shared_examples 'GRPC metadata delivery works OK' do
317
358
  call.run_batch(@client_queue, @client_tag, deadline, client_ops)
318
359
 
319
360
  # server gets the invocation but sends no metadata back
320
- recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
361
+ rcv_thread.join
321
362
  expect(recvd_rpc).to_not eq nil
322
363
  server_call = recvd_rpc.call
323
364
  server_ops = {
@@ -351,7 +392,7 @@ describe 'the http client/server' do
351
392
 
352
393
  after(:example) do
353
394
  @ch.close
354
- @server.close
395
+ @server.close(@server_queue, deadline)
355
396
  end
356
397
 
357
398
  it_behaves_like 'basic GRPC message delivery is OK' do
@@ -377,7 +418,7 @@ describe 'the secure http client/server' do
377
418
  end
378
419
 
379
420
  after(:example) do
380
- @server.close
421
+ @server.close(@server_queue, deadline)
381
422
  end
382
423
 
383
424
  it_behaves_like 'basic GRPC message delivery is OK' do
@@ -51,7 +51,7 @@ describe GRPC::ActiveCall do
51
51
  end
52
52
 
53
53
  after(:each) do
54
- @server.close
54
+ @server.close(@server_queue, deadline)
55
55
  end
56
56
 
57
57
  describe 'restricted view methods' do
@@ -54,6 +54,7 @@ describe 'ClientStub' do
54
54
  before(:each) do
55
55
  Thread.abort_on_exception = true
56
56
  @server = nil
57
+ @server_queue = nil
57
58
  @method = 'an_rpc_method'
58
59
  @pass = OK
59
60
  @fail = INTERNAL
@@ -61,7 +62,7 @@ describe 'ClientStub' do
61
62
  end
62
63
 
63
64
  after(:each) do
64
- @server.close unless @server.nil?
65
+ @server.close(@server_queue) unless @server_queue.nil?
65
66
  end
66
67
 
67
68
  describe '#new' do
@@ -136,10 +136,6 @@ describe GRPC::RpcServer do
136
136
  @ch = GRPC::Core::Channel.new(@host, nil)
137
137
  end
138
138
 
139
- after(:each) do
140
- @server.close
141
- end
142
-
143
139
  describe '#new' do
144
140
  it 'can be created with just some args' do
145
141
  opts = { a_channel_arg: 'an_arg' }
@@ -344,10 +340,6 @@ describe GRPC::RpcServer do
344
340
  @srv = RpcServer.new(**server_opts)
345
341
  end
346
342
 
347
- after(:each) do
348
- @srv.stop
349
- end
350
-
351
343
  it 'should return NOT_FOUND status on unknown methods', server: true do
352
344
  @srv.handle(EchoService)
353
345
  t = Thread.new { @srv.run }
@@ -527,10 +519,6 @@ describe GRPC::RpcServer do
527
519
  @srv = RpcServer.new(**server_opts)
528
520
  end
529
521
 
530
- after(:each) do
531
- @srv.stop
532
- end
533
-
534
522
  it 'should send connect metadata to the client', server: true do
535
523
  service = EchoService.new
536
524
  @srv.handle(service)
@@ -54,7 +54,7 @@ describe Server do
54
54
 
55
55
  it 'fails if the server is closed' do
56
56
  s = Server.new(@cq, nil)
57
- s.close
57
+ s.close(@cq)
58
58
  expect { s.start }.to raise_error(RuntimeError)
59
59
  end
60
60
  end
@@ -62,19 +62,19 @@ describe Server do
62
62
  describe '#destroy' do
63
63
  it 'destroys a server ok' do
64
64
  s = start_a_server
65
- blk = proc { s.destroy }
65
+ blk = proc { s.destroy(@cq) }
66
66
  expect(&blk).to_not raise_error
67
67
  end
68
68
 
69
69
  it 'can be called more than once without error' do
70
70
  s = start_a_server
71
71
  begin
72
- blk = proc { s.destroy }
72
+ blk = proc { s.destroy(@cq) }
73
73
  expect(&blk).to_not raise_error
74
74
  blk.call
75
75
  expect(&blk).to_not raise_error
76
76
  ensure
77
- s.close
77
+ s.close(@cq)
78
78
  end
79
79
  end
80
80
  end
@@ -83,16 +83,16 @@ describe Server do
83
83
  it 'closes a server ok' do
84
84
  s = start_a_server
85
85
  begin
86
- blk = proc { s.close }
86
+ blk = proc { s.close(@cq) }
87
87
  expect(&blk).to_not raise_error
88
88
  ensure
89
- s.close
89
+ s.close(@cq)
90
90
  end
91
91
  end
92
92
 
93
93
  it 'can be called more than once without error' do
94
94
  s = start_a_server
95
- blk = proc { s.close }
95
+ blk = proc { s.close(@cq) }
96
96
  expect(&blk).to_not raise_error
97
97
  blk.call
98
98
  expect(&blk).to_not raise_error
@@ -105,14 +105,14 @@ describe Server do
105
105
  blk = proc do
106
106
  s = Server.new(@cq, nil)
107
107
  s.add_http2_port('localhost:0')
108
- s.close
108
+ s.close(@cq)
109
109
  end
110
110
  expect(&blk).to_not raise_error
111
111
  end
112
112
 
113
113
  it 'fails if the server is closed' do
114
114
  s = Server.new(@cq, nil)
115
- s.close
115
+ s.close(@cq)
116
116
  expect { s.add_http2_port('localhost:0') }.to raise_error(RuntimeError)
117
117
  end
118
118
  end
@@ -123,14 +123,14 @@ describe Server do
123
123
  blk = proc do
124
124
  s = Server.new(@cq, nil)
125
125
  s.add_http2_port('localhost:0', cert)
126
- s.close
126
+ s.close(@cq)
127
127
  end
128
128
  expect(&blk).to_not raise_error
129
129
  end
130
130
 
131
131
  it 'fails if the server is closed' do
132
132
  s = Server.new(@cq, nil)
133
- s.close
133
+ s.close(@cq)
134
134
  blk = proc { s.add_http2_port('localhost:0', cert) }
135
135
  expect(&blk).to raise_error(RuntimeError)
136
136
  end
@@ -53,3 +53,5 @@ RSpec.configure do |config|
53
53
  include RSpec::LoggingHelper
54
54
  config.capture_log_messages
55
55
  end
56
+
57
+ RSpec::Expectations.configuration.warn_about_potential_false_positives = false
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
4
+ version: 0.10.0
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-24 00:00:00.000000000 Z
11
+ date: 2015-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -259,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
259
  - !ruby/object:Gem::Version
260
260
  version: '0'
261
261
  requirements:
262
- - libgrpc ~> 0.9.1 needs to be installed
262
+ - libgrpc ~> 0.10.0 needs to be installed
263
263
  rubyforge_project:
264
264
  rubygems_version: 2.4.3
265
265
  signing_key: