Module: Magicprotorb::ServiceBuilder
- Defined in:
- lib/magicprotorb/service_builder.rb
Overview
Synthesizes gRPC Service/Stub classes from the service descriptors in a FileDescriptorProto — the runtime equivalent of a generated ‘*_services_pb.rb`. Requires the optional `grpc` gem, loaded lazily so that message-only users never pay for it.
Class Method Summary collapse
- .build(file) ⇒ Object
- .build_service(package, service) ⇒ Object
- .define_service_class(full_name, methods) ⇒ Object
- .qualify(package, name) ⇒ Object
-
.strip(type_name) ⇒ Object
Descriptor type references are fully-qualified with a leading dot (“.greet.HelloRequest”); the pool is keyed without it.
Class Method Details
.build(file) ⇒ Object
11 12 13 14 15 |
# File 'lib/magicprotorb/service_builder.rb', line 11 def build(file) require "grpc" package = file.package file.service.each { |service| build_service(package, service) } end |
.build_service(package, service) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/magicprotorb/service_builder.rb', line 17 def build_service(package, service) # Use to_h to read the repeated `method` field: ServiceDescriptorProto#method # collides with Ruby's Object#method. descriptor = service.to_h name = descriptor[:name] full_name = qualify(package, name) service_class = define_service_class(full_name, descriptor[:method] || []) mod = Registrar.ensure_module(Naming.package_modules(package) + [Naming.constant_name(name)]) mod.const_set(:Service, service_class) unless mod.const_defined?(:Service, false) mod.const_set(:Stub, service_class.rpc_stub_class) unless mod.const_defined?(:Stub, false) end |
.define_service_class(full_name, methods) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/magicprotorb/service_builder.rb', line 31 def define_service_class(full_name, methods) pool = Google::Protobuf::DescriptorPool.generated_pool Class.new do include GRPC::GenericService self.marshal_class_method = :encode self.unmarshal_class_method = :decode self.service_name = full_name methods.each do |method| request = pool.lookup(ServiceBuilder.strip(method[:input_type])).msgclass response = pool.lookup(ServiceBuilder.strip(method[:output_type])).msgclass # stream(...) is provided by GenericService's DSL inside the class body. request = stream(request) if method[:client_streaming] response = stream(response) if method[:server_streaming] rpc method[:name].to_sym, request, response end end end |
.qualify(package, name) ⇒ Object
52 53 54 |
# File 'lib/magicprotorb/service_builder.rb', line 52 def qualify(package, name) package.nil? || package.empty? ? name : "#{package}.#{name}" end |
.strip(type_name) ⇒ Object
Descriptor type references are fully-qualified with a leading dot (“.greet.HelloRequest”); the pool is keyed without it.
58 59 60 |
# File 'lib/magicprotorb/service_builder.rb', line 58 def strip(type_name) type_name.sub(/\A\./, "") end |