grpc 0.13.0.pre1.1-universal-darwin

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.

Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/etc/roots.pem +5114 -0
  3. data/grpc_c.32.ruby +0 -0
  4. data/grpc_c.64.ruby +0 -0
  5. data/src/ruby/bin/apis/google/protobuf/empty.rb +44 -0
  6. data/src/ruby/bin/apis/pubsub_demo.rb +256 -0
  7. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  8. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  9. data/src/ruby/bin/grpc_ruby_interop_client +33 -0
  10. data/src/ruby/bin/grpc_ruby_interop_server +33 -0
  11. data/src/ruby/bin/interop/interop_client.rb +51 -0
  12. data/src/ruby/bin/interop/interop_server.rb +50 -0
  13. data/src/ruby/bin/math.rb +32 -0
  14. data/src/ruby/bin/math_client.rb +147 -0
  15. data/src/ruby/bin/math_server.rb +206 -0
  16. data/src/ruby/bin/math_services.rb +27 -0
  17. data/src/ruby/bin/noproto_client.rb +108 -0
  18. data/src/ruby/bin/noproto_server.rb +112 -0
  19. data/src/ruby/ext/grpc/extconf.rb +129 -0
  20. data/src/ruby/ext/grpc/rb_byte_buffer.c +70 -0
  21. data/src/ruby/ext/grpc/rb_byte_buffer.h +47 -0
  22. data/src/ruby/ext/grpc/rb_call.c +908 -0
  23. data/src/ruby/ext/grpc/rb_call.h +66 -0
  24. data/src/ruby/ext/grpc/rb_call_credentials.c +319 -0
  25. data/src/ruby/ext/grpc/rb_call_credentials.h +46 -0
  26. data/src/ruby/ext/grpc/rb_channel.c +432 -0
  27. data/src/ruby/ext/grpc/rb_channel.h +47 -0
  28. data/src/ruby/ext/grpc/rb_channel_args.c +169 -0
  29. data/src/ruby/ext/grpc/rb_channel_args.h +53 -0
  30. data/src/ruby/ext/grpc/rb_channel_credentials.c +268 -0
  31. data/src/ruby/ext/grpc/rb_channel_credentials.h +47 -0
  32. data/src/ruby/ext/grpc/rb_completion_queue.c +183 -0
  33. data/src/ruby/ext/grpc/rb_completion_queue.h +55 -0
  34. data/src/ruby/ext/grpc/rb_event_thread.c +158 -0
  35. data/src/ruby/ext/grpc/rb_event_thread.h +37 -0
  36. data/src/ruby/ext/grpc/rb_grpc.c +336 -0
  37. data/src/ruby/ext/grpc/rb_grpc.h +85 -0
  38. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +560 -0
  39. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +843 -0
  40. data/src/ruby/ext/grpc/rb_loader.c +72 -0
  41. data/src/ruby/ext/grpc/rb_loader.h +40 -0
  42. data/src/ruby/ext/grpc/rb_server.c +400 -0
  43. data/src/ruby/ext/grpc/rb_server.h +47 -0
  44. data/src/ruby/ext/grpc/rb_server_credentials.c +284 -0
  45. data/src/ruby/ext/grpc/rb_server_credentials.h +47 -0
  46. data/src/ruby/lib/grpc.rb +44 -0
  47. data/src/ruby/lib/grpc/2.0/grpc_c.bundle +0 -0
  48. data/src/ruby/lib/grpc/2.1/grpc_c.bundle +0 -0
  49. data/src/ruby/lib/grpc/2.2/grpc_c.bundle +0 -0
  50. data/src/ruby/lib/grpc/2.3/grpc_c.bundle +0 -0
  51. data/src/ruby/lib/grpc/core/time_consts.rb +71 -0
  52. data/src/ruby/lib/grpc/errors.rb +62 -0
  53. data/src/ruby/lib/grpc/generic/active_call.rb +488 -0
  54. data/src/ruby/lib/grpc/generic/bidi_call.rb +218 -0
  55. data/src/ruby/lib/grpc/generic/client_stub.rb +471 -0
  56. data/src/ruby/lib/grpc/generic/rpc_desc.rb +147 -0
  57. data/src/ruby/lib/grpc/generic/rpc_server.rb +504 -0
  58. data/src/ruby/lib/grpc/generic/service.rb +234 -0
  59. data/src/ruby/lib/grpc/grpc.rb +34 -0
  60. data/src/ruby/lib/grpc/logconfig.rb +59 -0
  61. data/src/ruby/lib/grpc/notifier.rb +60 -0
  62. data/src/ruby/lib/grpc/version.rb +33 -0
  63. data/src/ruby/pb/README.md +42 -0
  64. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  65. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  66. data/src/ruby/pb/grpc/health/v1alpha/health.rb +29 -0
  67. data/src/ruby/pb/grpc/health/v1alpha/health_services.rb +28 -0
  68. data/src/ruby/pb/test/client.rb +469 -0
  69. data/src/ruby/pb/test/proto/empty.rb +15 -0
  70. data/src/ruby/pb/test/proto/messages.rb +80 -0
  71. data/src/ruby/pb/test/proto/test.rb +14 -0
  72. data/src/ruby/pb/test/proto/test_services.rb +64 -0
  73. data/src/ruby/pb/test/server.rb +253 -0
  74. data/src/ruby/spec/call_credentials_spec.rb +57 -0
  75. data/src/ruby/spec/call_spec.rb +163 -0
  76. data/src/ruby/spec/channel_credentials_spec.rb +97 -0
  77. data/src/ruby/spec/channel_spec.rb +177 -0
  78. data/src/ruby/spec/client_server_spec.rb +475 -0
  79. data/src/ruby/spec/completion_queue_spec.rb +42 -0
  80. data/src/ruby/spec/generic/active_call_spec.rb +373 -0
  81. data/src/ruby/spec/generic/client_stub_spec.rb +476 -0
  82. data/src/ruby/spec/generic/rpc_desc_spec.rb +331 -0
  83. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +138 -0
  84. data/src/ruby/spec/generic/rpc_server_spec.rb +576 -0
  85. data/src/ruby/spec/generic/service_spec.rb +345 -0
  86. data/src/ruby/spec/pb/health/checker_spec.rb +232 -0
  87. data/src/ruby/spec/server_credentials_spec.rb +94 -0
  88. data/src/ruby/spec/server_spec.rb +209 -0
  89. data/src/ruby/spec/spec_helper.rb +69 -0
  90. data/src/ruby/spec/testdata/README +1 -0
  91. data/src/ruby/spec/testdata/ca.pem +15 -0
  92. data/src/ruby/spec/testdata/server1.key +16 -0
  93. data/src/ruby/spec/testdata/server1.pem +16 -0
  94. data/src/ruby/spec/time_consts_spec.rb +89 -0
  95. metadata +319 -0
@@ -0,0 +1,218 @@
1
+ # Copyright 2015-2016, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'forwardable'
31
+ require 'grpc/grpc'
32
+
33
+ # GRPC contains the General RPC module.
34
+ module GRPC
35
+ # The BiDiCall class orchestrates exection of a BiDi stream on a client or
36
+ # server.
37
+ class BidiCall
38
+ include Core::CallOps
39
+ include Core::StatusCodes
40
+ include Core::TimeConsts
41
+
42
+ # Creates a BidiCall.
43
+ #
44
+ # BidiCall should only be created after a call is accepted. That means
45
+ # different things on a client and a server. On the client, the call is
46
+ # accepted after call.invoke. On the server, this is after call.accept.
47
+ #
48
+ # #initialize cannot determine if the call is accepted or not; so if a
49
+ # call that's not accepted is used here, the error won't be visible until
50
+ # the BidiCall#run is called.
51
+ #
52
+ # deadline is the absolute deadline for the call.
53
+ #
54
+ # @param call [Call] the call used by the ActiveCall
55
+ # @param q [CompletionQueue] the completion queue used to accept
56
+ # the call
57
+ # @param marshal [Function] f(obj)->string that marshal requests
58
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
59
+ # @param metadata_tag [Object] tag object used to collect metadata
60
+ def initialize(call, q, marshal, unmarshal, metadata_tag: nil)
61
+ fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
62
+ unless q.is_a? Core::CompletionQueue
63
+ fail(ArgumentError, 'not a CompletionQueue')
64
+ end
65
+ @call = call
66
+ @cq = q
67
+ @marshal = marshal
68
+ @op_notifier = nil # signals completion on clients
69
+ @readq = Queue.new
70
+ @unmarshal = unmarshal
71
+ @metadata_tag = metadata_tag
72
+ end
73
+
74
+ # Begins orchestration of the Bidi stream for a client sending requests.
75
+ #
76
+ # The method either returns an Enumerator of the responses, or accepts a
77
+ # block that can be invoked with each response.
78
+ #
79
+ # @param requests the Enumerable of requests to send
80
+ # @op_notifier a Notifier used to signal completion
81
+ # @return an Enumerator of requests to yield
82
+ def run_on_client(requests, op_notifier, &blk)
83
+ @op_notifier = op_notifier
84
+ @enq_th = Thread.new { write_loop(requests) }
85
+ @loop_th = start_read_loop
86
+ each_queued_msg(&blk)
87
+ end
88
+
89
+ # Begins orchestration of the Bidi stream for a server generating replies.
90
+ #
91
+ # N.B. gen_each_reply is a func(Enumerable<Requests>)
92
+ #
93
+ # It takes an enumerable of requests as an arg, in case there is a
94
+ # relationship between the stream of requests and the stream of replies.
95
+ #
96
+ # This does not mean that must necessarily be one. E.g, the replies
97
+ # produced by gen_each_reply could ignore the received_msgs
98
+ #
99
+ # @param gen_each_reply [Proc] generates the BiDi stream replies.
100
+ def run_on_server(gen_each_reply)
101
+ replys = gen_each_reply.call(each_queued_msg)
102
+ @loop_th = start_read_loop(is_client: false)
103
+ write_loop(replys, is_client: false)
104
+ end
105
+
106
+ private
107
+
108
+ END_OF_READS = :end_of_reads
109
+ END_OF_WRITES = :end_of_writes
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
+
118
+ # performs a read using @call.run_batch, ensures metadata is set up
119
+ def read_using_run_batch
120
+ ops = { RECV_MESSAGE => nil }
121
+ ops[RECV_INITIAL_METADATA] = nil unless @metadata_tag.nil?
122
+ batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
123
+ unless @metadata_tag.nil?
124
+ @call.metadata = batch_result.metadata
125
+ @metadata_tag = nil
126
+ end
127
+ batch_result
128
+ end
129
+
130
+ # each_queued_msg yields each message on this instances readq
131
+ #
132
+ # - messages are added to the readq by #read_loop
133
+ # - iteration ends when the instance itself is added
134
+ def each_queued_msg
135
+ return enum_for(:each_queued_msg) unless block_given?
136
+ count = 0
137
+ loop do
138
+ GRPC.logger.debug("each_queued_msg: waiting##{count}")
139
+ count += 1
140
+ req = @readq.pop
141
+ GRPC.logger.debug("each_queued_msg: req = #{req}")
142
+ fail req if req.is_a? StandardError
143
+ break if req.equal?(END_OF_READS)
144
+ yield req
145
+ end
146
+ end
147
+
148
+ def write_loop(requests, is_client: true)
149
+ GRPC.logger.debug('bidi-write-loop: starting')
150
+ write_tag = Object.new
151
+ count = 0
152
+ requests.each do |req|
153
+ GRPC.logger.debug("bidi-write-loop: #{count}")
154
+ count += 1
155
+ payload = @marshal.call(req)
156
+ @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
157
+ SEND_MESSAGE => payload)
158
+ end
159
+ GRPC.logger.debug("bidi-write-loop: #{count} writes done")
160
+ if is_client
161
+ GRPC.logger.debug("bidi-write-loop: client sent #{count}, waiting")
162
+ @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
163
+ SEND_CLOSE_FROM_CLIENT => nil)
164
+ GRPC.logger.debug('bidi-write-loop: done')
165
+ notify_done
166
+ end
167
+ GRPC.logger.debug('bidi-write-loop: finished')
168
+ rescue StandardError => e
169
+ GRPC.logger.warn('bidi-write-loop: failed')
170
+ GRPC.logger.warn(e)
171
+ notify_done
172
+ raise e
173
+ end
174
+
175
+ # starts the read loop
176
+ def start_read_loop(is_client: true)
177
+ Thread.new do
178
+ GRPC.logger.debug('bidi-read-loop: starting')
179
+ begin
180
+ read_tag = Object.new
181
+ count = 0
182
+ # queue the initial read before beginning the loop
183
+ loop do
184
+ GRPC.logger.debug("bidi-read-loop: #{count}")
185
+ count += 1
186
+ batch_result = read_using_run_batch
187
+
188
+ # handle the next message
189
+ if batch_result.message.nil?
190
+ GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
191
+
192
+ if is_client
193
+ batch_result = @call.run_batch(@cq, read_tag, INFINITE_FUTURE,
194
+ RECV_STATUS_ON_CLIENT => nil)
195
+ @call.status = batch_result.status
196
+ batch_result.check_status
197
+ GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
198
+ end
199
+
200
+ @readq.push(END_OF_READS)
201
+ GRPC.logger.debug('bidi-read-loop: done reading!')
202
+ break
203
+ end
204
+
205
+ # push the latest read onto the queue and continue reading
206
+ res = @unmarshal.call(batch_result.message)
207
+ @readq.push(res)
208
+ end
209
+ rescue StandardError => e
210
+ GRPC.logger.warn('bidi: read-loop failed')
211
+ GRPC.logger.warn(e)
212
+ @readq.push(e) # let each_queued_msg terminate with this error
213
+ end
214
+ GRPC.logger.debug('bidi-read-loop: finished')
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,471 @@
1
+ # Copyright 2015-2016, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ require 'grpc/generic/active_call'
31
+ require 'grpc/version'
32
+
33
+ # GRPC contains the General RPC module.
34
+ module GRPC
35
+ # rubocop:disable Metrics/ParameterLists
36
+
37
+ # ClientStub represents an endpoint used to send requests to GRPC servers.
38
+ class ClientStub
39
+ include Core::StatusCodes
40
+ include Core::TimeConsts
41
+
42
+ # Default timeout is infinity.
43
+ DEFAULT_TIMEOUT = INFINITE_FUTURE
44
+
45
+ # setup_channel is used by #initialize to constuct a channel from its
46
+ # arguments.
47
+ def self.setup_channel(alt_chan, host, creds, **kw)
48
+ unless alt_chan.nil?
49
+ fail(TypeError, '!Channel') unless alt_chan.is_a?(Core::Channel)
50
+ return alt_chan
51
+ end
52
+ kw['grpc.primary_user_agent'] = "grpc-ruby/#{VERSION}"
53
+ unless creds.is_a?(Core::ChannelCredentials) || creds.is_a?(Symbol)
54
+ fail(TypeError, '!ChannelCredentials or Symbol')
55
+ end
56
+ Core::Channel.new(host, kw, creds)
57
+ end
58
+
59
+ # Allows users of the stub to modify the propagate mask.
60
+ #
61
+ # This is an advanced feature for use when making calls to another gRPC
62
+ # server whilst running in the handler of an existing one.
63
+ attr_writer :propagate_mask
64
+
65
+ # Creates a new ClientStub.
66
+ #
67
+ # Minimally, a stub is created with the just the host of the gRPC service
68
+ # it wishes to access, e.g.,
69
+ #
70
+ # my_stub = ClientStub.new(example.host.com:50505,
71
+ # :this_channel_is_insecure)
72
+ #
73
+ # Any arbitrary keyword arguments are treated as channel arguments used to
74
+ # configure the RPC connection to the host.
75
+ #
76
+ # There are some specific keyword args that are not used to configure the
77
+ # channel:
78
+ #
79
+ # - :channel_override
80
+ # when present, this must be a pre-created GRPC::Channel. If it's
81
+ # present the host and arbitrary keyword arg areignored, and the RPC
82
+ # connection uses this channel.
83
+ #
84
+ # - :timeout
85
+ # when present, this is the default timeout used for calls
86
+ #
87
+ # @param host [String] the host the stub connects to
88
+ # @param q [Core::CompletionQueue] used to wait for events
89
+ # @param creds [Core::ChannelCredentials|Symbol] the channel credentials, or
90
+ # :this_channel_is_insecure
91
+ # @param channel_override [Core::Channel] a pre-created channel
92
+ # @param timeout [Number] the default timeout to use in requests
93
+ # @param kw [KeywordArgs]the channel arguments
94
+ def initialize(host, q, creds,
95
+ channel_override: nil,
96
+ timeout: nil,
97
+ propagate_mask: nil,
98
+ **kw)
99
+ fail(TypeError, '!CompletionQueue') unless q.is_a?(Core::CompletionQueue)
100
+ @queue = q
101
+ @ch = ClientStub.setup_channel(channel_override, host, creds, **kw)
102
+ alt_host = kw[Core::Channel::SSL_TARGET]
103
+ @host = alt_host.nil? ? host : alt_host
104
+ @propagate_mask = propagate_mask
105
+ @timeout = timeout.nil? ? DEFAULT_TIMEOUT : timeout
106
+ end
107
+
108
+ # request_response sends a request to a GRPC server, and returns the
109
+ # response.
110
+ #
111
+ # == Flow Control ==
112
+ # This is a blocking call.
113
+ #
114
+ # * it does not return until a response is received.
115
+ #
116
+ # * the requests is sent only when GRPC core's flow control allows it to
117
+ # be sent.
118
+ #
119
+ # == Errors ==
120
+ # An RuntimeError is raised if
121
+ #
122
+ # * the server responds with a non-OK status
123
+ #
124
+ # * the deadline is exceeded
125
+ #
126
+ # == Return Value ==
127
+ #
128
+ # If return_op is false, the call returns the response
129
+ #
130
+ # If return_op is true, the call returns an Operation, calling execute
131
+ # on the Operation returns the response.
132
+ #
133
+ # == Keyword Args ==
134
+ #
135
+ # Unspecified keyword arguments are treated as metadata to be sent to the
136
+ # server.
137
+ #
138
+ # @param method [String] the RPC method to call on the GRPC server
139
+ # @param req [Object] the request sent to the server
140
+ # @param marshal [Function] f(obj)->string that marshals requests
141
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
142
+ # @param timeout [Numeric] (optional) the max completion time in seconds
143
+ # @param deadline [Time] (optional) the time the request should complete
144
+ # @param parent [Core::Call] a prior call whose reserved metadata
145
+ # will be propagated by this one.
146
+ # @param credentials [Core::CallCredentials] credentials to use when making
147
+ # the call
148
+ # @param return_op [true|false] return an Operation if true
149
+ # @return [Object] the response received from the server
150
+ def request_response(method, req, marshal, unmarshal,
151
+ deadline: nil,
152
+ timeout: nil,
153
+ return_op: false,
154
+ parent: nil,
155
+ credentials: nil,
156
+ **kw)
157
+ c = new_active_call(method, marshal, unmarshal,
158
+ deadline: deadline,
159
+ timeout: timeout,
160
+ parent: parent,
161
+ credentials: credentials)
162
+ return c.request_response(req, **kw) unless return_op
163
+
164
+ # return the operation view of the active_call; define #execute as a
165
+ # new method for this instance that invokes #request_response.
166
+ op = c.operation
167
+ op.define_singleton_method(:execute) do
168
+ c.request_response(req, **kw)
169
+ end
170
+ op
171
+ end
172
+
173
+ # client_streamer sends a stream of requests to a GRPC server, and
174
+ # returns a single response.
175
+ #
176
+ # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
177
+ # #each enumeration protocol. In the simplest case, requests will be an
178
+ # array of marshallable objects; in typical case it will be an Enumerable
179
+ # that allows dynamic construction of the marshallable objects.
180
+ #
181
+ # == Flow Control ==
182
+ # This is a blocking call.
183
+ #
184
+ # * it does not return until a response is received.
185
+ #
186
+ # * each requests is sent only when GRPC core's flow control allows it to
187
+ # be sent.
188
+ #
189
+ # == Errors ==
190
+ # An RuntimeError is raised if
191
+ #
192
+ # * the server responds with a non-OK status
193
+ #
194
+ # * the deadline is exceeded
195
+ #
196
+ # == Return Value ==
197
+ #
198
+ # If return_op is false, the call consumes the requests and returns
199
+ # the response.
200
+ #
201
+ # If return_op is true, the call returns the response.
202
+ #
203
+ # == Keyword Args ==
204
+ #
205
+ # Unspecified keyword arguments are treated as metadata to be sent to the
206
+ # server.
207
+ #
208
+ # @param method [String] the RPC method to call on the GRPC server
209
+ # @param requests [Object] an Enumerable of requests to send
210
+ # @param marshal [Function] f(obj)->string that marshals requests
211
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
212
+ # @param timeout [Numeric] (optional) the max completion time in seconds
213
+ # @param deadline [Time] (optional) the time the request should complete
214
+ # @param return_op [true|false] return an Operation if true
215
+ # @param parent [Core::Call] a prior call whose reserved metadata
216
+ # will be propagated by this one.
217
+ # @param credentials [Core::CallCredentials] credentials to use when making
218
+ # the call
219
+ # @return [Object|Operation] the response received from the server
220
+ def client_streamer(method, requests, marshal, unmarshal,
221
+ deadline: nil,
222
+ timeout: nil,
223
+ return_op: false,
224
+ parent: nil,
225
+ credentials: nil,
226
+ **kw)
227
+ c = new_active_call(method, marshal, unmarshal,
228
+ deadline: deadline,
229
+ timeout: timeout,
230
+ parent: parent,
231
+ credentials: credentials)
232
+ return c.client_streamer(requests, **kw) unless return_op
233
+
234
+ # return the operation view of the active_call; define #execute as a
235
+ # new method for this instance that invokes #client_streamer.
236
+ op = c.operation
237
+ op.define_singleton_method(:execute) do
238
+ c.client_streamer(requests, **kw)
239
+ end
240
+ op
241
+ end
242
+
243
+ # server_streamer sends one request to the GRPC server, which yields a
244
+ # stream of responses.
245
+ #
246
+ # responses provides an enumerator over the streamed responses, i.e. it
247
+ # follows Ruby's #each iteration protocol. The enumerator blocks while
248
+ # waiting for each response, stops when the server signals that no
249
+ # further responses will be supplied. If the implicit block is provided,
250
+ # it is executed with each response as the argument and no result is
251
+ # returned.
252
+ #
253
+ # == Flow Control ==
254
+ # This is a blocking call.
255
+ #
256
+ # * the request is sent only when GRPC core's flow control allows it to
257
+ # be sent.
258
+ #
259
+ # * the request will not complete until the server sends the final
260
+ # response followed by a status message.
261
+ #
262
+ # == Errors ==
263
+ # An RuntimeError is raised if
264
+ #
265
+ # * the server responds with a non-OK status when any response is
266
+ # * retrieved
267
+ #
268
+ # * the deadline is exceeded
269
+ #
270
+ # == Return Value ==
271
+ #
272
+ # if the return_op is false, the return value is an Enumerator of the
273
+ # results, unless a block is provided, in which case the block is
274
+ # executed with each response.
275
+ #
276
+ # if return_op is true, the function returns an Operation whose #execute
277
+ # method runs server streamer call. Again, Operation#execute either
278
+ # calls the given block with each response or returns an Enumerator of the
279
+ # responses.
280
+ #
281
+ # == Keyword Args ==
282
+ #
283
+ # Unspecified keyword arguments are treated as metadata to be sent to the
284
+ # server.
285
+ #
286
+ # @param method [String] the RPC method to call on the GRPC server
287
+ # @param req [Object] the request sent to the server
288
+ # @param marshal [Function] f(obj)->string that marshals requests
289
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
290
+ # @param timeout [Numeric] (optional) the max completion time in seconds
291
+ # @param deadline [Time] (optional) the time the request should complete
292
+ # @param return_op [true|false]return an Operation if true
293
+ # @param parent [Core::Call] a prior call whose reserved metadata
294
+ # will be propagated by this one.
295
+ # @param credentials [Core::CallCredentials] credentials to use when making
296
+ # the call
297
+ # @param blk [Block] when provided, is executed for each response
298
+ # @return [Enumerator|Operation|nil] as discussed above
299
+ def server_streamer(method, req, marshal, unmarshal,
300
+ deadline: nil,
301
+ timeout: nil,
302
+ return_op: false,
303
+ parent: nil,
304
+ credentials: nil,
305
+ **kw,
306
+ &blk)
307
+ c = new_active_call(method, marshal, unmarshal,
308
+ deadline: deadline,
309
+ timeout: timeout,
310
+ parent: parent,
311
+ credentials: credentials)
312
+ return c.server_streamer(req, **kw, &blk) unless return_op
313
+
314
+ # return the operation view of the active_call; define #execute
315
+ # as a new method for this instance that invokes #server_streamer
316
+ op = c.operation
317
+ op.define_singleton_method(:execute) do
318
+ c.server_streamer(req, **kw, &blk)
319
+ end
320
+ op
321
+ end
322
+
323
+ # bidi_streamer sends a stream of requests to the GRPC server, and yields
324
+ # a stream of responses.
325
+ #
326
+ # This method takes an Enumerable of requests, and returns and enumerable
327
+ # of responses.
328
+ #
329
+ # == requests ==
330
+ #
331
+ # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
332
+ # #each enumeration protocol. In the simplest case, requests will be an
333
+ # array of marshallable objects; in typical case it will be an
334
+ # Enumerable that allows dynamic construction of the marshallable
335
+ # objects.
336
+ #
337
+ # == responses ==
338
+ #
339
+ # This is an enumerator of responses. I.e, its #next method blocks
340
+ # waiting for the next response. Also, if at any point the block needs
341
+ # to consume all the remaining responses, this can be done using #each or
342
+ # #collect. Calling #each or #collect should only be done if
343
+ # the_call#writes_done has been called, otherwise the block will loop
344
+ # forever.
345
+ #
346
+ # == Flow Control ==
347
+ # This is a blocking call.
348
+ #
349
+ # * the call completes when the next call to provided block returns
350
+ # * [False]
351
+ #
352
+ # * the execution block parameters are two objects for sending and
353
+ # receiving responses, each of which blocks waiting for flow control.
354
+ # E.g, calles to bidi_call#remote_send will wait until flow control
355
+ # allows another write before returning; and obviously calls to
356
+ # responses#next block until the next response is available.
357
+ #
358
+ # == Termination ==
359
+ #
360
+ # As well as sending and receiving messages, the block passed to the
361
+ # function is also responsible for:
362
+ #
363
+ # * calling bidi_call#writes_done to indicate no further reqs will be
364
+ # sent.
365
+ #
366
+ # * returning false if once the bidi stream is functionally completed.
367
+ #
368
+ # Note that response#next will indicate that there are no further
369
+ # responses by throwing StopIteration, but can only happen either
370
+ # if bidi_call#writes_done is called.
371
+ #
372
+ # To terminate the RPC correctly the block:
373
+ #
374
+ # * must call bidi#writes_done and then
375
+ #
376
+ # * either return false as soon as there is no need for other responses
377
+ #
378
+ # * loop on responses#next until no further responses are available
379
+ #
380
+ # == Errors ==
381
+ # An RuntimeError is raised if
382
+ #
383
+ # * the server responds with a non-OK status when any response is
384
+ # * retrieved
385
+ #
386
+ # * the deadline is exceeded
387
+ #
388
+ #
389
+ # == Keyword Args ==
390
+ #
391
+ # Unspecified keyword arguments are treated as metadata to be sent to the
392
+ # server.
393
+ #
394
+ # == Return Value ==
395
+ #
396
+ # if the return_op is false, the return value is an Enumerator of the
397
+ # results, unless a block is provided, in which case the block is
398
+ # executed with each response.
399
+ #
400
+ # if return_op is true, the function returns an Operation whose #execute
401
+ # method runs the Bidi call. Again, Operation#execute either calls a
402
+ # given block with each response or returns an Enumerator of the
403
+ # responses.
404
+ #
405
+ # @param method [String] the RPC method to call on the GRPC server
406
+ # @param requests [Object] an Enumerable of requests to send
407
+ # @param marshal [Function] f(obj)->string that marshals requests
408
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
409
+ # @param timeout [Numeric] (optional) the max completion time in seconds
410
+ # @param deadline [Time] (optional) the time the request should complete
411
+ # @param parent [Core::Call] a prior call whose reserved metadata
412
+ # will be propagated by this one.
413
+ # @param credentials [Core::CallCredentials] credentials to use when making
414
+ # the call
415
+ # @param return_op [true|false] return an Operation if true
416
+ # @param blk [Block] when provided, is executed for each response
417
+ # @return [Enumerator|nil|Operation] as discussed above
418
+ def bidi_streamer(method, requests, marshal, unmarshal,
419
+ deadline: nil,
420
+ timeout: nil,
421
+ return_op: false,
422
+ parent: nil,
423
+ credentials: nil,
424
+ **kw,
425
+ &blk)
426
+ c = new_active_call(method, marshal, unmarshal,
427
+ deadline: deadline,
428
+ timeout: timeout,
429
+ parent: parent,
430
+ credentials: credentials)
431
+
432
+ return c.bidi_streamer(requests, **kw, &blk) unless return_op
433
+
434
+ # return the operation view of the active_call; define #execute
435
+ # as a new method for this instance that invokes #bidi_streamer
436
+ op = c.operation
437
+ op.define_singleton_method(:execute) do
438
+ c.bidi_streamer(requests, **kw, &blk)
439
+ end
440
+ op
441
+ end
442
+
443
+ private
444
+
445
+ # Creates a new active stub
446
+ #
447
+ # @param method [string] the method being called.
448
+ # @param marshal [Function] f(obj)->string that marshals requests
449
+ # @param unmarshal [Function] f(string)->obj that unmarshals responses
450
+ # @param parent [Grpc::Call] a parent call, available when calls are
451
+ # made from server
452
+ # @param timeout [TimeConst]
453
+ def new_active_call(method, marshal, unmarshal,
454
+ deadline: nil,
455
+ timeout: nil,
456
+ parent: nil,
457
+ credentials: nil)
458
+ if deadline.nil?
459
+ deadline = from_relative_time(timeout.nil? ? @timeout : timeout)
460
+ end
461
+ call = @ch.create_call(@queue,
462
+ parent, # parent call
463
+ @propagate_mask, # propagation options
464
+ method,
465
+ nil, # host use nil,
466
+ deadline)
467
+ call.set_credentials! credentials unless credentials.nil?
468
+ ActiveCall.new(call, @queue, marshal, unmarshal, deadline, started: false)
469
+ end
470
+ end
471
+ end