module GRPC::GenericService::Dsl

Provides a simple DSL to describe RPC services.

E.g, a Maths service that uses the serializable messages DivArgs, DivReply and Num might define its endpoint uses the following way:

rpc :div DivArgs, DivReply # single request, single response rpc :sum stream(Num), Num # streamed input, single response rpc :fib FibArgs, stream(Num) # single request, streamed response rpc :div_many stream(DivArgs), stream(DivReply)

# streamed req and resp

Each 'rpc' adds an RpcDesc to classes including this module, and assert_rpc_descs_have_methods is used to ensure the including class provides methods with signatures that support all the descriptors.

Attributes

marshal_class_method[W]

This configures the method names that the serializable message implementation uses to marshal and unmarshal messages.

  • unmarshal_class method must be a class method on the serializable

message type that takes a string (byte stream) and produces and object

and produces a serialized string.

The Dsl verifies that the types in the descriptor have both the unmarshal and marshal methods.

service_name[RW]

This allows configuration of the service name.

unmarshal_class_method[W]

This configures the method names that the serializable message implementation uses to marshal and unmarshal messages.

  • unmarshal_class method must be a class method on the serializable

message type that takes a string (byte stream) and produces and object

and produces a serialized string.

The Dsl verifies that the types in the descriptor have both the unmarshal and marshal methods.

Public Class Methods

new(host, creds, **kw) click to toggle source

@param host [String] the host the stub connects to @param creds [Core::ChannelCredentials|Symbol] The channel

credentials to use, or :this_channel_is_insecure otherwise

@param kw [KeywordArgs] the channel arguments, plus any optional

args for configuring the client's channel
Calls superclass method
# File src/ruby/lib/grpc/generic/service.rb, line 157
def initialize(host, creds, **kw)
  super(host, creds, **kw)
end

Public Instance Methods

assert_can_marshal(cls) click to toggle source
# File src/ruby/lib/grpc/generic/service.rb, line 123
def assert_can_marshal(cls)
  cls = cls.type if cls.is_a? RpcDesc::Stream
  mth = unmarshal_class_method
  unless cls.methods.include? mth
    fail(ArgumentError, "#{cls} needs #{cls}.#{mth}")
  end
  mth = marshal_class_method
  return if cls.methods.include? mth
  fail(ArgumentError, "#{cls} needs #{cls}.#{mth}")
end
inherited(subclass) click to toggle source
# File src/ruby/lib/grpc/generic/service.rb, line 105
def inherited(subclass)
  # Each subclass should have a distinct class variable with its own
  # rpc_descs
  subclass.rpc_descs.merge!(rpc_descs)
  subclass.service_name = service_name
end
marshal_class_method() click to toggle source

the name of the instance method used to marshal events to a byte stream.

# File src/ruby/lib/grpc/generic/service.rb, line 114
def marshal_class_method
  @marshal_class_method ||= :marshal
end
rpc(name, input, output) click to toggle source

Adds an RPC spec.

Takes the RPC name and the classes representing the types to be serialized, and adds them to the including classes rpc_desc hash.

input and output should both have the methods marshal and unmarshal that are responsible for writing and reading an object instance from a byte buffer respectively.

@param name [String] the name of the rpc @param input [Object] the input parameter's class @param output [Object] the output parameter's class

# File src/ruby/lib/grpc/generic/service.rb, line 92
def rpc(name, input, output)
  fail(DuplicateRpcName, name) if rpc_descs.key? name
  assert_can_marshal(input)
  assert_can_marshal(output)
  rpc_descs[name] = RpcDesc.new(name, input, output,
                                marshal_class_method,
                                unmarshal_class_method)
  define_method(GenericService.underscore(name.to_s).to_sym) do |*|
    fail GRPC::BadStatus.new_status_exception(
      GRPC::Core::StatusCodes::UNIMPLEMENTED)
  end
end
rpc_descs() click to toggle source

the RpcDescs defined for this GenericService, keyed by name.

# File src/ruby/lib/grpc/generic/service.rb, line 142
def rpc_descs
  @rpc_descs ||= {}
end
rpc_stub_class() click to toggle source

Creates a rpc client class with methods for accessing the methods currently in rpc_descs.

# File src/ruby/lib/grpc/generic/service.rb, line 148
def rpc_stub_class
  descs = rpc_descs
  route_prefix = service_name
  Class.new(ClientStub) do
    # @param host [String] the host the stub connects to
    # @param creds [Core::ChannelCredentials|Symbol] The channel
    #     credentials to use, or :this_channel_is_insecure otherwise
    # @param kw [KeywordArgs] the channel arguments, plus any optional
    #                         args for configuring the client's channel
    def initialize(host, creds, **kw)
      super(host, creds, **kw)
    end

    # Used define_method to add a method for each rpc_desc.  Each method
    # calls the base class method for the given descriptor.
    descs.each_pair do |name, desc|
      mth_name = GenericService.underscore(name.to_s).to_sym
      marshal = desc.marshal_proc
      unmarshal = desc.unmarshal_proc(:output)
      route = "/#{route_prefix}/#{name}"
      if desc.request_response?
        define_method(mth_name) do |req, metadata = {}|
          GRPC.logger.debug("calling #{@host}:#{route}")
          request_response(route, req, marshal, unmarshal, **metadata)
        end
      elsif desc.client_streamer?
        define_method(mth_name) do |reqs, metadata = {}|
          GRPC.logger.debug("calling #{@host}:#{route}")
          client_streamer(route, reqs, marshal, unmarshal, **metadata)
        end
      elsif desc.server_streamer?
        define_method(mth_name) do |req, metadata = {}, &blk|
          GRPC.logger.debug("calling #{@host}:#{route}")
          server_streamer(route, req, marshal, unmarshal, **metadata, &blk)
        end
      else  # is a bidi_stream
        define_method(mth_name) do |reqs, metadata = {}, &blk|
          GRPC.logger.debug("calling #{@host}:#{route}")
          bidi_streamer(route, reqs, marshal, unmarshal, **metadata, &blk)
        end
      end
    end
  end
end
stream(cls) click to toggle source

@param cls [Class] the class of a serializable type @return cls wrapped in a RpcDesc::Stream

# File src/ruby/lib/grpc/generic/service.rb, line 136
def stream(cls)
  assert_can_marshal(cls)
  RpcDesc::Stream.new(cls)
end
unmarshal_class_method() click to toggle source

the name of the class method used to unmarshal from a byte stream.

# File src/ruby/lib/grpc/generic/service.rb, line 119
def unmarshal_class_method
  @unmarshal_class_method ||= :unmarshal
end