Index: third_party/grpc/src/ruby/lib/grpc/generic/rpc_desc.rb |
diff --git a/third_party/grpc/src/ruby/lib/grpc/generic/rpc_desc.rb b/third_party/grpc/src/ruby/lib/grpc/generic/rpc_desc.rb |
new file mode 100644 |
index 0000000000000000000000000000000000000000..526b2ba5b61118c639e8621a0c8eda22582b8f85 |
--- /dev/null |
+++ b/third_party/grpc/src/ruby/lib/grpc/generic/rpc_desc.rb |
@@ -0,0 +1,147 @@ |
+# Copyright 2015-2016, 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. |
+ |
+require 'grpc/grpc' |
+ |
+# GRPC contains the General RPC module. |
+module GRPC |
+ # RpcDesc is a Descriptor of an RPC method. |
+ class RpcDesc < Struct.new(:name, :input, :output, :marshal_method, |
+ :unmarshal_method) |
+ include Core::StatusCodes |
+ |
+ # Used to wrap a message class to indicate that it needs to be streamed. |
+ class Stream |
+ attr_accessor :type |
+ |
+ def initialize(type) |
+ @type = type |
+ end |
+ end |
+ |
+ # @return [Proc] { |instance| marshalled(instance) } |
+ def marshal_proc |
+ proc { |o| o.class.method(marshal_method).call(o).to_s } |
+ end |
+ |
+ # @param [:input, :output] target determines whether to produce the an |
+ # unmarshal Proc for the rpc input parameter or |
+ # its output parameter |
+ # |
+ # @return [Proc] An unmarshal proc { |marshalled(instance)| instance } |
+ def unmarshal_proc(target) |
+ fail ArgumentError unless [:input, :output].include?(target) |
+ unmarshal_class = method(target).call |
+ unmarshal_class = unmarshal_class.type if unmarshal_class.is_a? Stream |
+ proc { |o| unmarshal_class.method(unmarshal_method).call(o) } |
+ end |
+ |
+ def run_server_method(active_call, mth) |
+ # While a server method is running, it might be cancelled, its deadline |
+ # might be reached, the handler could throw an unknown error, or a |
+ # well-behaved handler could throw a StatusError. |
+ if request_response? |
+ req = active_call.remote_read |
+ resp = mth.call(req, active_call.single_req_view) |
+ active_call.remote_send(resp) |
+ elsif client_streamer? |
+ resp = mth.call(active_call.multi_req_view) |
+ active_call.remote_send(resp) |
+ elsif server_streamer? |
+ req = active_call.remote_read |
+ replys = mth.call(req, active_call.single_req_view) |
+ replys.each { |r| active_call.remote_send(r) } |
+ else # is a bidi_stream |
+ active_call.run_server_bidi(mth) |
+ end |
+ send_status(active_call, OK, 'OK', **active_call.output_metadata) |
+ rescue BadStatus => e |
+ # this is raised by handlers that want GRPC to send an application error |
+ # code and detail message and some additional app-specific metadata. |
+ GRPC.logger.debug("app err:#{active_call}, status:#{e.code}:#{e.details}") |
+ send_status(active_call, e.code, e.details, **e.metadata) |
+ rescue Core::CallError => e |
+ # This is raised by GRPC internals but should rarely, if ever happen. |
+ # Log it, but don't notify the other endpoint.. |
+ GRPC.logger.warn("failed call: #{active_call}\n#{e}") |
+ rescue Core::OutOfTime |
+ # This is raised when active_call#method.call exceeeds the deadline |
+ # event. Send a status of deadline exceeded |
+ GRPC.logger.warn("late call: #{active_call}") |
+ send_status(active_call, DEADLINE_EXCEEDED, 'late') |
+ rescue StandardError => e |
+ # This will usuaally be an unhandled error in the handling code. |
+ # Send back a UNKNOWN status to the client |
+ GRPC.logger.warn("failed handler: #{active_call}; sending status:UNKNOWN") |
+ GRPC.logger.warn(e) |
+ send_status(active_call, UNKNOWN, 'no reason given') |
+ end |
+ |
+ def assert_arity_matches(mth) |
+ if request_response? || server_streamer? |
+ if mth.arity != 2 |
+ fail arity_error(mth, 2, "should be #{mth.name}(req, call)") |
+ end |
+ else |
+ if mth.arity != 1 |
+ fail arity_error(mth, 1, "should be #{mth.name}(call)") |
+ end |
+ end |
+ end |
+ |
+ def request_response? |
+ !input.is_a?(Stream) && !output.is_a?(Stream) |
+ end |
+ |
+ def client_streamer? |
+ input.is_a?(Stream) && !output.is_a?(Stream) |
+ end |
+ |
+ def server_streamer? |
+ !input.is_a?(Stream) && output.is_a?(Stream) |
+ end |
+ |
+ def bidi_streamer? |
+ input.is_a?(Stream) && output.is_a?(Stream) |
+ end |
+ |
+ def arity_error(mth, want, msg) |
+ "##{mth.name}: bad arg count; got:#{mth.arity}, want:#{want}, #{msg}" |
+ end |
+ |
+ def send_status(active_client, code, details, **kw) |
+ details = 'Not sure why' if details.nil? |
+ GRPC.logger.debug("Sending status #{code}:#{details}") |
+ active_client.send_status(code, details, code == OK, **kw) |
+ rescue StandardError => e |
+ GRPC.logger.warn("Could not send status #{code}:#{details}") |
+ GRPC.logger.warn(e) |
+ end |
+ end |
+end |