lib/httpx/plugins/grpc.rb in httpx-0.15.4 vs lib/httpx/plugins/grpc.rb in httpx-0.16.0
- old
+ new
@@ -47,11 +47,10 @@
}.freeze
class << self
def load_dependencies(*)
require "stringio"
- require "google/protobuf"
require "httpx/plugins/grpc/message"
require "httpx/plugins/grpc/call"
end
def configure(klass)
@@ -59,49 +58,51 @@
klass.plugin(:compression)
klass.plugin(:stream)
end
def extra_options(options)
- Class.new(options.class) do
- def_option(:grpc_service, <<-OUT)
- String(value)
- OUT
-
- def_option(:grpc_compression, <<-OUT)
- case value
- when true, false
- value
- else
- value.to_s
- end
- OUT
-
- def_option(:grpc_rpcs, <<-OUT)
- Hash[value]
- OUT
-
- def_option(:grpc_deadline, <<-OUT)
- raise Error, ":grpc_deadline must be positive" unless value.positive?
-
- value
- OUT
-
- def_option(:call_credentials, <<-OUT)
- raise Error, ":call_credentials must respond to #call" unless value.respond_to?(:call)
-
- value
- OUT
- end.new(options).merge(
+ options.merge(
fallback_protocol: "h2",
http2_settings: { wait_for_handshake: false },
grpc_rpcs: {}.freeze,
grpc_compression: false,
grpc_deadline: DEADLINE
)
end
end
+ module OptionsMethods
+ def option_grpc_service(value)
+ String(value)
+ end
+
+ def option_grpc_compression(value)
+ case value
+ when true, false
+ value
+ else
+ value.to_s
+ end
+ end
+
+ def option_grpc_rpcs(value)
+ Hash[value]
+ end
+
+ def option_grpc_deadline(value)
+ raise TypeError, ":grpc_deadline must be positive" unless value.positive?
+
+ value
+ end
+
+ def option_call_credentials(value)
+ raise TypeError, ":call_credentials must respond to #call" unless value.respond_to?(:call)
+
+ value
+ end
+ end
+
module ResponseMethods
attr_reader :trailing_metadata
def merge_headers(trailers)
@trailing_metadata = Hash[trailers]
@@ -138,21 +139,56 @@
rpc_opts = {
deadline: @options.grpc_deadline,
}.merge(opts)
- with(grpc_rpcs: @options.grpc_rpcs.merge(
- rpc_name.underscore => [rpc_name, input, output, rpc_opts]
- ).freeze)
+ session_class = Class.new(self.class) do
+ class_eval(<<-OUT, __FILE__, __LINE__ + 1)
+ def #{rpc_name}(input, **opts)
+ rpc_execute("#{rpc_name}", input, **opts)
+ end
+ OUT
+ end
+
+ session_class.new(@options.merge(
+ grpc_rpcs: @options.grpc_rpcs.merge(
+ rpc_name.underscore => [rpc_name, input, output, rpc_opts]
+ ).freeze
+ ))
end
def build_stub(origin, service: nil, compression: false)
scheme = @options.ssl.empty? ? "http" : "https"
origin = URI.parse("#{scheme}://#{origin}")
- with(origin: origin, grpc_service: service, grpc_compression: compression)
+ session = self
+
+ if service && service.respond_to?(:rpc_descs)
+ # it's a grpc generic service
+ service.rpc_descs.each do |rpc_name, rpc_desc|
+ rpc_opts = {
+ marshal_method: rpc_desc.marshal_method,
+ unmarshal_method: rpc_desc.unmarshal_method,
+ }
+
+ input = rpc_desc.input
+ input = input.type if input.respond_to?(:type)
+
+ output = rpc_desc.output
+ if output.respond_to?(:type)
+ rpc_opts[:stream] = true
+ output = output.type
+ end
+
+ session = session.rpc(rpc_name, input, output, **rpc_opts)
+ end
+
+ service = service.service_name
+ end
+
+ session.with(origin: origin, grpc_service: service, grpc_compression: compression)
end
def execute(rpc_method, input,
deadline: DEADLINE,
metadata: nil,
@@ -164,11 +200,11 @@
end
private
def rpc_execute(rpc_name, input, **opts)
- rpc_name, input_enc, output_enc, rpc_opts = @options.grpc_rpcs[rpc_name.to_s] || raise(Error, "#{rpc_name}: undefined service")
+ rpc_name, input_enc, output_enc, rpc_opts = @options.grpc_rpcs[rpc_name]
exec_opts = rpc_opts.merge(opts)
marshal_method ||= exec_opts.delete(:marshal_method) || MARSHAL_METHOD
unmarshal_method ||= exec_opts.delete(:unmarshal_method) || UNMARSHAL_METHOD
@@ -227,19 +263,9 @@
else
Message.encode(input, deflater: deflater)
end
build_request(:post, uri, headers: headers, body: body)
- end
-
- def respond_to_missing?(meth, *, &blk)
- @options.grpc_rpcs.key?(meth.to_s) || super
- end
-
- def method_missing(meth, *args, **kwargs, &blk)
- return rpc_execute(meth, *args, **kwargs, &blk) if @options.grpc_rpcs.key?(meth.to_s)
-
- super
end
end
end
register_plugin :grpc, GRPC
end